«v t Hlou/ Kampf
Li t in
MIKROCOMPUTER
Klaus Kämpf: CP/M 2.2 Assembler-Listing
ISBN 3-925074-1 1 -2
1. Auflage, Dezember 1985
(c) 1985 by « Ä
MICROCOMPUTER
Noppiusstr . 1 95100 Aachen
CP/M ist ein Warenzeichen der Firma Digital Research Inc. (DRI).DRI ist ebenfalls im Besitz der Copyrights von CP/M. Der Verlagbehält sich aber alle Rechte an der Dokumentierung der Softwareund der speziellen Aufbereitung und Darstellung des Stoffes vor.
Alle Rechte vorbehalten. Kein Teil dieses Buches darf inirgendeinem Verfahren reproduziert oder in EDV-Anlagenverarbeitet werden.
Alle in diesem Buch wiedergegebenen Schaltungen, Verfahren undProgramme werden ohne Rücksicht auf die Patentlage mitgeteilt unddürfen nicht gewerblich genutzt werden.
Alle Angaben in diesem Buch wurden mit größtmöglicher Sorgfalterarbeitet bzw. zusammengestellt. Trotzdem sind Fehler nichtganz auszuschließen. Der Verlag und der Autor sehen sich deshalbgezwungen, darauf hinzuweisen, daß sie weder eine Garantie nochdie juristische Verantwortung oder irgendeine Haftung für Folgen,die auf fehlerhafte Angaben zurückgehen, übernehmen können. Fürdie Mitteilung eventueller Fehler sind Autor und Verlag jederzeitdankbar.
Vorwort
Vorwort
Das Betriebsystem CP/M ist seit Jahren das Standard-Betrieb-system für 8080- und Z80-Mikrocomputer. Viele derzeit erhält-liche Bücher, befassen sich ausführlich mit der Bedienung desCP/M und der Nutzung der verschiedenen Betriebssystem-Funk-tionen.Das vorliegende Buch bietet nun erstmals einen Einblick indie inneren Abläufe des CP/M 2.2 und beschreibt ausführlichdie Arbeitsweise dieses Betriebsystems. Neben einer Beschrei-bung der internen Datenformate und der Diskettenparameter,wird jede BDOS-Funktion in ihrem Ablauf dokumentiert. Daranschliessen sich die kommentierten Source-Listings der beidenCP/M-Teile CCP und BDOS an. Für diejenigen Anwender, die sichein CP/M-BIOS selber schreiben wollen, v/erden noch Tips undTricks zur Verbesserung des CP/M 2.2 gegeben.
Aachen, im November 1985
Klaus Kämpf
„ . Inhalt* *
Inhaltsverzeichnis
Vorwort 3
Inhaltsverzeichnis 5
Grundlagen 7Einleitung 7CCP, BDOS, BIOS 8Speicheraufteilung 8Disketten - 10Dateien 1 1Directory 11Blöcke 12Records 12Directory-Einträge 13Userbereiche .- • 14Öffnen und Schliessen von Files 14Eintragsnummern 15Extends 15Extendgruppen 16
Datenformate 17Aufbau eines Eintrages 17Aufbau eines File Control Block 19
Diskparameter 23Disk Parameter Header 23Disk Parameter Block 26
BDOS-Funktionen 29
BIOS-Funktionen 51
Hinv/eise zu den Listings 59
CCP-Listing 61
BDOS-Listing 123
Tips & Tricks 237
Labels 241
Grundlagen
Einleitung
Die Geschichte des Betriebsystems CP/M ist eng verknüpft mitder Entwicklung der Mikroprozessoren und Mikrocomputer. Diefolgende Einleitung soll daher einen kurzen Rückblick auf dieEntstehung und weitere Entwicklung des CP/M geben:
Im Herbst 1973 kündigte die amerikanische ElektronikfirmaIntel, einen Mikroprozessor mit der Bezeichnung '8080' alsNachfolger ihres Prozessors '8008' an.Der 8080 war damals der erste Mikroprozessor, der nicht nurdiskrete Logik ersetzte, sondern auch zum Einsatz als Zen-traleinheit (CPU) für Mikrocomputer geeignet war. Im April1974 kamen dann die ersten Exemplare des 8080 zu einem Preisvon etwa 360 Dollar auf den Markt.
Einer der ersten Mikrocomputer mit dem 8080 als Zentralein-heit war der 'Altair 8800'.Der Altair 8800 wurde im Januar 1975 als Bausatz von derZeitschrift 'Populär Electronics* vorgestellt. InclusiveProzessor, Netzteil, Hauptplatine, binärer Ein- und Ausgabeund einem Speicher von 256 Bytes (i) kostete dieser Bausatz395 Dollar (damals ca. 1500 DM).
Der Altair 8800 war aus mehreren Einzelplatinen aufgebaut,die alle auf einer gemeinsamen Busplatine steckten. Eingroßer Vorteil dieses Aufbaus war, daß auch Zusatzplatinenanderer Firmen betrieben werden konnten.'Digital Microsystems1 war die erste Firma, die einen 'Disk-Controller1 zum Anschluss von 8 Zoll Diskettenlaufwerken anden Altair 8800 anbot und auch ein Betriebssystem dazu lie-ferte. Unter der Bezeichnung 'Control Program for Micro-computer', kurz 'CP/M1, wurde dieses Betriebssystem auch ge-trennt verkauft und entwickelte sich rasch zu einem Standard-Betriebssystem für 8080-Mikrocomputer.
Das erste CP/M (Versionsnummer 1.3, später 1.4) war auffolgende Grundkonfiguration abgestimmt:
- Einen Fernschreiber (Teletype, TTY) oder ein Bildschirm-terminal (Cathode Ray Tube, CRT) zur Ein- und Ausgabe
- Einen Lochstreifenleser (Paper Tape Reader, RDR) und -stan-zer (Paper Tape Punch, PUN) als Hintergrundspeicher
- 8 Zoll Diskettenlaufwerke im IBM 3740-Standard als Massen-speicher
Gedacht war ein solches System vor allem zur Entwicklung vonProgrammen für den 8080 Mikroprozessor. Noch heute zeugen dievon Digital Research mitgelieferten Programme EDf ASM oderDDT davon.
!l
! i
Grundlagen
CCP, BDOS, BIOS
Um die Große des Betriebssystems möglichst klein zu halten,wurde das CP/M in drei verschiedene Teile aufgespalten:
CCP (Console Command Processor)'Bef ehls-Bearbeiter ' . Zuständig für die Interpretierung derEingabe und Ausführung der grundlegenen Befehle wie DIR,ERA etc.
- BDOS (Basic Disk Operating System)Betriebssystem-Kern. Zuständig für die Verwaltung der Lauf-werke und der gesamten Ein- und Ausgabe.
- BIOS (Basic Input Output System)Systemabhängiger Teil. Zuständig für die Ansteuerung derhardwaresei t igen Systemkomponeriten .
Der CCP bildet die Benutzerebene des Betriebssystems, überdie der Anwender Befehle eingeben und Programme starten kann.Da nach dem Start eines Programms die Benutzerebene überflüs-sig ist, kann der vom CCP eingenommene Speicherplatz vomjeweils laufenden Programm mitbenutzt werden.Der CCP ist ein in sich abgeschlossenes Programm, daß, wienormale CP/M-Programme auch, Funktionen des BDOS benutzt.
Das BDOS ist der eigentliche Betriebssystem-Kern und aufallen CP/M Rechnern identisch. Dadurch ist die Kompatibilitätzwischen allen Rechnern die CP/M verwenden garantiert.
Das BIOS bildet die 'Schnittstelle' zwischen dem BDOS und derHardware des Computers.
Notwendig für Anwenderprogramme sind nur die beiden Teile'BDOS1 und 'BIOS1. Sie werden zusammen auch als ' FDOS ' be-zeichnet.
Speicheraufteilung
Damit das CP/M in verschiedenen Speichergrößen ablaufen kann,ist der Speicherbereich in dem das CP/M liegt nicht fest-gelegt. Statt dessen ist die erste Speicherseite (256 Bytes)für Systeminf ormatiorien reserviert und beinhaltet auch den l'Bezugspunkt' zum CP/M in Form eines Sprungbefehls.
Ab der zweiten Seite beginnt der Speicherbereich für Anwen-derprogramme, dio sogenannte 'Transient Program Area1, kurzTPA. Die TPA reicht bis zur ersten Adresse des CP/M, daßimmer am oberen Speicherende liegt.
Wichtig für den Betrieb von CP/M ist, daß der Speicher durch-gehend ist und bei der Adresse OOOOK beginnt. Da Anwender-
S
Grundlagen
programme immer ab einer fester Adresse arbeiten, ist dadurcheine einheitliche Startadresse der TPA festgelegt, was ersteinen Programmaustausch zwischen CP/M-Rechnern ermöglicht.
Die Speicheraufteilung im CP/M sieht im Überblick so aus
+ ---------------- + oberes Speicherende
FBASE
CBASE
TBASE
BOOT:
1st
1
11I
t1
1t1
1
1
BIOS
BDOS
CCP
TPA
System-parameter
lll
i1
t
1
1
1
1*
l•
Startadresse des FDOS
Startadresse des CCP
0100H
OOOOH
An der Adresse BOOT befindet sich grundsätzlich ein Sprungzur Warmstartroutine des BIOS. Diese Routine lädt nach Be-endigung eines Programms den CCP und das BDOS neu in denSpeicher und startet danach wieder den CCP. Das Sprungzielist immer der zweite Eintrag in der BlOS-Sprungtabelle, alsoBIOS + 0003H.Daraus kann ein Programm auch die Startadresse des BIOSberechnen und, falls es das BDOS nicht braucht, auch den vomBDOS belegten Speicherbereich nutzen.
Läßt ein Programm den Speicherplatz über CBASE unberührt, sokann es auch durch ein einfaches 'RET1 die Kontrolle wiederzurück an den CCP geben.
An der Adresse BOOT + 5 (normalerweise 0005H) steht einSprung nach FBASE, der die Verbindung zwischen Programmen unddem FDOS herstellt. Auch der CCP benutzt diesen Sprungbefehlbei der Anforderung von FDOS-Funktionen.Dieses Sprungziel kann aber durch gewisse Programme (z.B.DDT) verändert werden.
Im normalen CP/M-Gebrauch ist die Zieladresse diesesder niedrigste, vom FDOS verwendete Speicherplatz,man den Speicherplatz des CCP mit zur TPA, soAdresse genau die
des CCP mithöchste TPA-Adresse
SprungesRechnet
ist diese+ 1
Grundlagen
Das DDT-Programm setzt dies insofern voraus, als daß es sichselbst 'unter' das FDOS legt und den Sprung nach FBASE aufsich selbst legt. Startet man im DDT ein Programm, so ist derDDT geschützt, solange das Programm die Sprungadresse alsobere Speichergrenze benutzt. Außerdem laufen im Trace-Modusdes DDT alle BDOS-Aufrufe über den DDT, der damit die Kon-trolle über das System behält.
Disketten
Das CP/M ist als single-user, single-tasking Betriebssystemausgelegt. Das heißt, daß das CP/M zu einer Zeit nur einenBenutzer und ein Programm bearbeiten kann und damit auchimmer nur ein Laufwerk und eine Datei (File) 'kennt1.
Jedes Laufwerk muß daher vor der Bearbeitung beim BDOS an-gemeldet werden, daß sich daraufhin auf dieses Laufwerk ein-stellt. Die zu einem Laufwerk gehörenden Daten und Tabellensind im BIOS gespeichert, daß sie auf Anfrage dem BDOS zurVerfügung stellt.
Das Anmelden dient dem BDOS zur Einstellung seiner internenParameter auf das neue Laufwerk bzw. auf die im Laufwerk be-findliche Diskette. Über verschiedene BDOS-Funktionen kanndie Diskette dann gelesen und geschrieben werden.
Zum Schreiben muß dem BDOS aber bekannt sein, welche Teileder Diskette bereits Daten enthalten und welche noch freisind. Aus diesem Grund wird bei der Laufwerks-Anmeldung eineBelegungstabelle der Diskette erstellt, die Auskunft überfreie und belegte Teile gibt. l
Zur Speicherung neuer Daten kann das BDOS dann die benötigtenInformationen dieser Tabelle entnehmen.Da sich das BDOS noch zusätzlich 'merkt', ob ein Laufwerkschonmal angeaieldet wurde oder nicht, braucht die Belegungs-tabelle nur dann erstellt zu werden, wenn das Laufwerk zumersten Mal angewählt wird.
Das BDOS beschreibt eine Diskette immer anhand der vorliegen-den Belegungstabeile, was bei einem unkontrollierten Disket-tenwechsel fatale Folgen haben kann.Zur Umgehung dieses Problems verfügt das CP/M über den soge-nannten Warmstart.
Durch einen Warmstart wird das BDOS neu geladen und dadurchsein 'Gedächtnis1 der bekannten Laufwerk gelöscht. Bei jederfolgenden Laufwerksanwahl wird dadurch die Belegungstabellejeweils neu erstellt.
Zum Diskettenwechsel ohne Warmstart, bietet das BDOS auch dieMöglichkeit einzelne Laufwerke ab- und neu wieder anzumelden.Der Warmstart nach einem Diskettenwechsel ist immer Aufgabe
10
Grundlagen
des Benutzers; wenn er den Warmstart vergisst, tritt dasProblem wieder auf.
Da Datensicherheit in einem Betriebssystem nunmal das Wich-tigste ist, ist im CP/M noch ein zweiter Schutzmechanismuseingebaut, die Prüftabelle.
Bei der Anmeldung eines Laufwerks wird, neben der Belegungs-tabelle, auch eine Prüfsumme über das Inhaltsverzeichnis derDiskette erstellt und gespeichert.Vor jeder Schreiboperation bildet das BDOS diese Prüfsummeneu und vergleicht sie mit der zuletzt für dieses Laufwerkerrechneten Prüfsumme, verglichen.Anhand der Differenz dieser beiden Summen, erkennt das BDOSeinen Diskettenwechsel und sperrt jeden weiteren Schreibzu-griff auf das Laufwerk.
Aus diesem Grund müssen im CP/M Diskettenwechsel dem Systemimmer ausdrücklich mitgeteilt werden. Das Anmelden einerDiskette wird auch als 'einloggen1 (engl. Log in) und dasAbmelden als 'ausloggen1 (engl. Log out) bezeichnet.
Dateien
Jede Diskette ist physikalisch in Spuren (engl. Tracks) undSektoren (engl. Sectors) aufgeteilt.Der Datentransfer von und zu der Diskette spielt sich immerin ganzen Sektoren ab. Aufgabe des Programms ist es, denSektorinhalt zu interpretieren und die einzelnen Bytes auszu-lesen.
Zur Vereinfachung von Diskettenoperationen werden im CP/Mwie in anderen Betriebssystemen auch - zusammenhängende In-formationen in Dateien (engl. Files) zusammengefasst.
Jede Datei hat einen Dateinamen (engl. Filename) und kannunter diesem Namen bearbeitet werden. Die Ansteuerung einzel-ner Spuren und Sektoren auf der Diskette wird vom Betriebs-system übernommen.
Dateinamen bestehen im CP/M aus bis zu 8 Zeichen, gefolgt vonbis zu 3 Zeichen zur Kennzeichnung eines Dateityps (engl.Filetype). Filename und Filetyp werden meist auch zusammenals Filename bezeichnet.
Die Directory
Die Information, welche Daten bzw. welche Files auf einerDiskette aufgezeichnet sind, ist am Anfang der Diskette imInhaltsverzeichnis (engl. Directory) enthalten.
11
K
M-, Grundlagen
;jf In der Directory stehen alle wichtigen Daten die das BDOS zur;i[ Bearbeitung der Diskette benötigt. Für jedes File sind dies:
l!{'• - Der Filenamen und Filetyp- Die Länge des Files
;,, - Die vom File belegten Bereiche auf der Diskette.
Fordert ein Programm bestimmte Daten unter Angabe eines File-namens an, so kann das BDOS aus den Directory-Informationenden exakten Sektor auf der Diskette berechnen.
Blöckei ' ""
ti!ll Das BDOS teilt jede Diskette in Blöcke (engl. Blocks) auf, um
damit den Verwaltungs- und Speicheraufwand für die Belegungs-tabelle zu verkleinern.
Während das CP/M 1.4 noch eine feste Blocklänge von 1 Kilo-byte hatte, ist die Länge eines Blocks im CP/M 2.2 variabelgehalten.
' ft ••, - "l C) Da die Belegungstabelle in Blöcken geführt wird, kann dasBDOS Diskettenplatz auch nur blockweise vergeben. Nachteildieser Aufteilung ist, daß ein File immer ganze Blöcke be-legt, auch wenn die tatsächliche Filelänge kleiner ist.
Records
Das CP/M 1.4 baut auf der physikalischen Sektorlänge des IBM3740 Formates (128 Bytes pro Sektor) auf.Alle Dateioperationen geschehen im CP/M 1.4 in 128 Byte'Portionen1 und aach die Länge eine Files wird in Vielfachenvon 128 Bytes gemessen.
CP/M 2.2 hat diese Rechenweise für Files übernommen, unter-scheidet aber zwischen Sektoren auf der Diskette und File-1 Portionen ' .Ein Sektor ist im CP/M 2.2 die kleinste physikalische Auf-zeichnungseinheit auf der Diskette. Eine Datei- ' Portion ' wirdim CP/M 2.2 als Record bezeichnet. Ein Record ist derkleinste Teil einer Datei den CP/M noch addressieren bzw.unterscheiden kann.
Die interne Bearbeitung von Disketten geschieht im CP/M 2.2immer in einzelnen Records. Der Name "Record1 wird daher imweiteren nicht nur in Verbindung mit Files, sondern auchallgemein für Diskettendaten benutzt.
Im Zusammenhang mit Disketten ist auch die Bezeichnung 'lo-gischer Sektor1 für einen Record üblich. Damit wird vor allemder Unterschied zwischen einem Sektor auf der Diskette ('phy-sikalischer Sektor1) und einem 'Sektor1, wie ihn das BDOS
1 2
Grundlagen
verarbeitet, deutlich gemacht.
Obwohl das BIOS eigentlich den physikalischen Teil des CP/Mbildet, geschieht Datentransfer zwischen BDOS und BIOS inlogischen Sektoren.Zum einen wird, z.B. beim Laden einer Datei in den Speicher,am BDOS 'vorbei1 geladen. Das heißt, daß das BDOS dem BIOSnur mitteilt wohin der nächste logische Sektor geladen werdensoll und den Rest dem BIOS überlässt.Der zweite Grund ist, daß das neue CP/M 2.2 nach der Ein-führung möglichst schnell Verbreitung finden sollte. Dazumusste der Aufwand zur Umstellung eines CP/M 1.4 BIOS auf dieCP/M 2.2 Version klein gehalten werden. Da das CP/M 1.4 nurmit dem IBM 3740 Diskettenformat arbeitet, können die Disk-ettenein- und ausgaberoutinen vom CP/M 1.4 BIOS zum CP/M 2.2BIOS übernommen werden.
Im CP/M 2.2 hat das BIOS die Aufgabe zwischen physikalischenund logischen Sektoren zu trennen.Der bei einer physikalischen Sektorlänge von mehr als 128Bytes notwendige Aufwand ist nacht ganz unerheblich.Das BIOS muß beim Lesen jeden physikalischen Sektor in lo-gische Sektoren .aufspalten und beim Schreiben logische Sek-toren zu einem physikalischen Sekto zusammenfassen.
CP/M 2.2 unterstützt dieses Zusammenfassen und Aufspalten(engl. Blocking and Deblocking) durch einen weiteren Para-meter, der den Lese/Schreibroutinen im BIOS übergeben wird.
Directory-Einträge
Die Directory enthält alle Informationen über die auf derDiskette gespeicherten Files. Dazu gehören neben dem File-namen und Filetyp, die Länge des Files und die von ihm beleg-ten Blocke.
Jedes File benutzt mindestens einen Eintrag (engl. Entry)innerhalb der Directory. Die Lange eines Eintrags ist im CP/Mauf 32 Bytes festgelegt. Damit passen in jeden Directory-Record genau 4 Einträge.Directory-Funktionen im BDOS geben daher meist einen Direc-tory-Code zurück, der die relative Nummer eines Eintrages imDirectory-Record angibt. Über diese Nummer können Programmeeinen Eintrag in der Directory 'finden' und selbst bear-beiten.
Als Directory-Bereich auf der Diskette, ist im CP/M 1.4 dererste Block reserviert. Damit beträgt die Höchstzahl an Ein-trägen auf einer CP/M 1.4 Diskette 64. Im CP/M 2.2 ist dieGröße der Directory in gewissen Grenzen frei wählbar.Es können bis zu 16 Blöcke als Directory reserviert werdenund auch die Anzahl der Einträge ist ein getrennter Para-meter. Bei der maximalen Blockgröße von 16 kbyte, sind im
1 3
Grundlagen
CP/M 2.2 maximal 16384 Directory-Einträge möglich
Userbereiche
Zur besseren Handhabung größerer Directories gibt es im CP/M2.2 sogenannte User-Bereiche (engl. User Areas).
Jeder Directory-Eintrag enthält eine zusätzliche Kennung, dieUsernummer (engl. User Number).
Das BDOS arbeitet immer nur innerhalb eines Userbereichs underkennt nur die Directory-Einträge, die innerhalb des aktuel-len Userbereichs liegen, d.h. die entsprechende Usernummerhaben.Eine Usernummer kann daher nicht einzelnen Files zugewiesenwerden, sondern immer nur dem BDOS als ganzem.
User-Bereiche können vom CCP aus mit dem 'USER'-Befehl an-gewählt werden. Das BDOS unterscheidet zwar bis zu 32 User-Bereiche, der CCP erlaubt jedoch nur die Anwahl der ersten16.
Öffnen und Schliessen von Files
Zum Arbeiten mit einem File benötigt das BDOS alle Infor-mationen des zum File gehörenden Directory-Eintrags.Zu diesem Zweck muß ein Programm, will es mit einem Filearbeiten, dieses File erst eröffnen (engl. open).
Dazu stellt das Programm dem BDOS einen 32Speicherbereich - den Datei Kontroll BlockControl Block, FCB) - zur Verfügung.
Byte großen(engl. File
Durch diese Speicherung der Directory-Informationen in einemgetrennten Bereich werden zwei Ziele erreicht:Erstens wird die Anzahl der Directory-Zugriffe erheblichreduziert, da das BDOS die Daten des Directory-Eintrags immerdem FCB entnimmt.Zweitens können dadurch, im Widerspruch zur 'Ein-Benutzer-Struktur* des BDOS, mehrere Files quasi-gleichzeitg bear-beitet werden.Bei jeder Fileoperation wird deiTi BDOS die Adresse des jewei-ligen FCB übergeben. Das BDOS entnimmt daraufhin die wich-tigsten Daten direkt dem FCB und speichert sie intern. Da-durch wird - aus der Sicht einer BDOS-Funktion - immer nurein File zu einer Zeit bearbeitet.Nach Abschluß der Fileoperation schreibt das BDOS die Datenzurück in den FCB, der damit immer die aktuellen Daten ent-hält.Ist die Bearbeitung eines Files beendet, so wird es wiedergeschlossen (engl. close).
1 4
Grundlagen
Beim Schliessen eines Files schreibt das BDOS die Infor-mationen des FCB wieder zurück in den Eintrag.Dieses Zurückschreiben ist aber nur dann wichtig, wenn dieInformationen des Eintrags (bzw. FCB) wirklich geändert wur-den. Im CP/M kann nur die Schreibfunktion die Größe einesFiles und damit die Daten des FCB beeinflussen.
BDOS-intern erhält daher jeder FCB eine getrennte Kennung,die Auskunft darüber gibt, ob eine Schreiboperation aufdiesem FCB^ausgeführt wurde oder nicht.Nach dem Öffnen wird diese Kennung auf 'nicht geschrieben1
bzw. 'nicht geändert1 (engl. not altered) gesetzt und beieiner Schreiboperation gelöscht.Die BDOS-Funktion 'File schließen1 aktualisiert einen Eintragnur, wenn diese Kennung gelöscht ist.
Eintragsnummern
Im CP/M 1.4 kann eine Diskette bis zu 256 Blöcken, bei 1kBlockgröße entsprechend 256 kbytes, umfassen. Blocknummernwerden jm CP/M 1.4 immer als 8-Bit Werte verwaltet.
Von den 32 Bytes eines Eintrags sind 16 Bytes für dieSpeicherung der vom File belegten Blocknummern vorgesehen.Pro Eintrag können damit im CP/M 1.4 maximal 16 Blöcke adres-siert werden, was einer Filegröße von 16 kbytes pro Eintragentspricht. Für jeweils 16k Daten ist daher im CP/M 1.4 eineigener Directory- Eintrag nötig.
In Records ausgedrückt entspricht die maximale FilegrÖße proEintrag bzw. FCB, 128 Records (128 * 128 Bytes = 16k Bytes).Da Recordnummern im CP/M immer relativ gezählt werden, istder Bereich der Recordnummern - bezogen auf den Eintrag - 0bis 127. Bei Erreichen der Recordnummer 128 wird im CP/M 1.4automatisch der nächste Eintrag aus der Directory gelesen unddie Nummerierung der Records wieder bei 0 angefangen.Jeder zu einem File gehörende Eintrag wird daher noch miteiner Eintragsnummer versehen.
Zur Anwahl eines bestimmten Records innerhalb eines Files,ist also sowohl die Record- als auch die Eintragsnummer anzu-geben.Die maximale Anzahl von Eintragen pro File ist im CP/M 1.4auf 16 begrenzt, sodaß ein File höchstens eine Größe von 256kbytes erreichen kann.
Extends
Diese Zählweise der Eintrags- und Recordnummern wurde beimÜbergang von CP/M 1.4 zu CP/M 2.2 aus Kompatibilitätsgründenbeibehalten.
Da das CP/M 2.2 aber mit verschiedenen Blockgrößen arbeiten
1 5
H'J
Grundlagen
III,
tf .
kann, trifft die Bezeichnung 'Eintragsnummer1 nicht mehr zu.Das CP/M 2.2 trennt aus diesem Grund zwischen den BegriffenExtend und Eintrag.Ein Extend im CP/M 2.2 entspricht dem Adressierungsbereicheines Eintrags im CP/M 1.4 - 16 kbyte.Ein Eintrag im CP/M 2.2 dagegen kann, bei der maximalenBlockgröße von 16 kbytes, bis zu 16 Extends enthalten.
Intern werden Files im CP/M 2.2 grundsätzlich in Extendsverwaltet, um so die Zählweise der Recordnummern von 0 bis127 zu erhalten.
Extendgruppen
Das CP/M 2.2 fasst noch zusätzlich jeweils 32 Extends zueiner Extendgruppe (engl. Extend Group) zusammen.Ein File kann aus bis zu 16 Extendgruppen aufgebaut sein, wasdie maximale Länge eines Files auf 65536 Records (8 Megabyte)begrenzt.
Die laufende Recordnummer eines Files wird BDOS-intern immerin den drei Teilen Extendgruppe, Extend und Record verwaltet.
16
Datenformate
Aufbau eines Directory-Eintrags
Ein Eintrag umfasst 32 Bytes und enthält alle Informationen,die das BDOS zur Lokalisierung der Daten auf der Diskettebenötigt. Das folgende Schema soll den prinzipiellen Aufbaueines Eintrages im CP/M 2.2 verdeutlichen:
J UN N1 N2 N3 N4 N5 N6 N7 N8 T1 T2 T3 EX S1 EG RC l
Pos. 0 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5
j BÖ Bn l
Pos. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
mitUN Usernummer des Files (0..31)
N1 N8 Filename (8 Zeichen)
T1...T3 Filetyp (3 Zeichen) und Fileattribut
EX Höchste Extendnummer des Eintrags (0..31)
S1 unbenutzt, immer 0
EG Höchste Extendgruppe des Eintrags (0..15)(auch als S2 bezeichnet)
RC Anzahl der Records im Extend EX (0..127)
B1...Bn Nummern der belegten Blöcke(Blocktabelle)
Die erste Position des Eintrags enthält die Nummer des User-bereiches zu dem das File gehört. Der Wert E5H an dieserStelle weist den Eintrag als unbelegt aus.
Die Positionen N1 bis N8 bzw. T1 bis T3 sind Filename undFiletyp des zum Eintrag gehörenden Files in Großschrift.
Umfasst ein Filenamen weniger als 8 Zeichen, so werden dienicht benutzten Stellen mit Leerzeichen aufgefüllt. Gleichesgilt auch für den Filetyp.
Da Filenamen und Filetyp ASCII-Wert sind, werden immer nurdie unteren 7 der 8 Bits an den Positionen N1 bis N8 und T1bis T3 ausgenutzt. Die höchsten Bits an den Positionen T1 bisT3 werden zur Kennzeichnung eines Fileattributes verwendet.CP/M 2.2 nutzt von den drei möglichen Attribut-Bits aber nurT1 und T2 für die Attribute 'Schreibgeschützt' und 'System-
1 7
Datenformate
file1 aus. Das dritte Bit kann von Anwenderprogrammeneigene Zwecke genutzt werden.
für
Bit 7 der Position T1 weist ein File als 'schreibgeschützt'aus. Vor jedem Schreibzugriff wird dieses Bit getestet und,falls es auf '1' steht, der Zugriff mit der Fehlermeldung'FILE R/O1 abgebrochen.Bit 7 der Position T2 zeigt das AttributDieses Attribut wird jedoch nicht vom BDOS,'DIR'-Befehl im CCP beachtet.
'Systemfile1
sondern nuran.vom
EX enthält die Extendnummer, EG die Extendgruppe des letztendurch den Eintrag abgedeckten Record. EX und EG werden, beimehreren Einträgen zu einem File, immer relativ zum File-anfang gerechnet
RC ist die Anzahl von Records im höchsten Extend (EX) desEintrages. RC liegt normalerweise im Bereich zwischen 0 und127.Ein Wert von 128 in RC zeigt an, daß auch der letzte Extendmit 128 Records gefüllt ist. In diesem Fall folgt noch einweiterer Eintrag (Folgeeintrag).
In der Blocktabelle stehen die vom File belegten Block-nummern .Die Blocktabelle kann bei 8-Bit Blocknummern bis zu 16 Blöckeund bei 16-Bit Blocknummern bis zu 8 Blöcke umfassen.
Datenformate
Aufbau eines File Control Blocks
Der Aufbau eines File Control Blocks entspricht dem einesDirectory-Eintrags.Vor dem Öffnen eines Files enthalt der FCB nur das Laufwerk,den Filename und den Filetyp des gewünschten Files. Zusätz-lich kann noch eine Extendnummer angegeben werden, sodaß einbestimmter Extend schon beim Öffnen erreicht wird.
Die Anwahl einer Extendgruppen ist nicht direkt möglich;geöffnet wird immer die erste Extendgruppe.
Zum Öffnen muß der FCB folgende Daten enthalten:
l LW N1 N2 N3 N4 N5 N6 N7 N8 T1 T2 T3 EX 0 0 0 i+ +
Pos. 0 1 2 3 4 5 6 7 8 9 10 1 1 12 1 3 31 32
mitLW Laufwerkscode
0 - Aktuelles Laufwerk1 - Laufwerk A2 - Laufwerk B
* • *
16 - Laufwerk P
N1...N8 Filename (8 Zeichen)
T1 T3 Filetyp (3 Zeichen)
EX Extendnummer
Die 'File offnen'-Funktion im BDOS durchsucht die Directorydes gewünschten Laufwerks nach einem passenden Eintrag undkopiert diesen in den FCB. Alle weiteren Filefunktionen desBDOS stützen sich nur noch auf die im FCB enthaltenen Infor-mationen.
Ein geöffneter FCB bezieht sich immer auf einen bestimmtenExtend des Files. Die genaue Recordnummer innerhalb diesesExtends wird in einem weiteren Byte an der Position 32 ge-speichert. Durch Vergleich dieser Recordnummer mit derhöchsten Recordnummer des Extends kann das BDOS entscheiden,wann das Ende eines Extends erreicht ist. Die genaue Belegungder 33 Bytes eines geöffneten FCB gibt das folgende Schema:
19
Datenformate
FCB nach dem Offnen:
Pos.
• LW N1 N2 N3 N4 N5 N6 N7 N8 T1 T2 T3 EX S1 EG RC !
0 1 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5
+ __ __ __ _ _ —— _ —- __ __ —.___— __ __ _ __ __ _ _ _ __ _._ _ _ .__ -_ _ ___ __ J^J JI
j BO Bn CR I• ___ ____ ___ _ _ _ ^^ _ , _r_ _ —„ _.._ _T ^ ^ ,__ ____„_»*-. — -i _ _^_ _- __ _^ __ ,__ „ _ _ _ _ _,„ ^ _^ 1Mf „_ _ _ __ _ , i
Pos. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
mitLW Nummer des Laufwerks
0 - Aktuelles Laufwerk1 - Laufwerk A2 - Laufwerk B
16 Laufwerk P
N1...N8 Filename (8 Zeichen)
T1...T3 Filetyp (3 Zeichen)
EX Aktuelle Extendnummer (0..31)
S1 unbenutzt, immer 0
EG Aktuelle Extendgruppe (0..15)
RC Anzahl der Records im Extend EX (0..127)
B1...Bn Nummern der belegten Blöcke(Blocktabelle)
CR Aktuelle Recordnummer im Extend EX (0..127)
Über die Position LW können vom BDOS auch nach dem Öffnennoch Files von verschiedenen Laufwerken unterschieden werden.
Ist LW nicht 0, so wird vor jeder Fileoperation das gewün-schte Laufwerk angewählt und nach Abschluss der Operationwieder auf das alte Laufwerk zurückgeschaltet.Nach der Anwahl des Laufwerks speichert das BDOS den Wert derLW-Position und setzt dort die aktuelle Usernummer ein. Da-durch entsprechend sich - BDOS-intern - FCB und Eintrag inden ersten 12 Positionen.
Die nächsten vier Bytes sind zwischen FCB und Eintrag unter-schiedlich: Da bei Fileoperationen immer mit einzelnen Re-cords gearbeitet wird, beschreibt ein FCB - anders als einEintrag - keine Filegröße, sondern einen bestimmten Record.
20
^ ••' •. Datenformate
EG und EX bilden im FCB die Nummer des Extends, in dem der zubearbeitende Record liegt. RC ist Anzahl von Records indiesem Extend.Die genaue Recördnummer innerhalb des Extends ist in derzusätzlichen Position CR enthalten.
B1 bis Bn entsprechend genau der Blocktabelle des Eintrags.Aus dieser Blocktabelle entnimmt das BDOS während der Bear-beitung die Blocknummer für den Diskettenzugriff.
Sequentieller Zugriff <-> Direkter Zugriff
Im CP/M 1.4 ist es Aufgabe des Programms die Eintrags- undRecördnummer im FCB zu setzen. Soll ein bestimmter Recordinnerhalb des Files erreicht werden, so muß das Programm dieExtend- und Recördnummer selbst berechnen und in den FCBeinsetzen.Aus der absoluten Recördnummer ergibt sich die Extendnummeraus der Division durch 128. Der Divisionrest ist die Recörd-nummer innerhalb des Extends. Diese Werte müssen aber immervor dem Öffnen gesetzt sein, damit das BDOS die richtigeBlocktabelle in den FCB überträgt.
Alle höheren Recordnummern können im CP/M 1.4 nur sequentiell(nacheinander) erreicht werden.Die im CP/M 1.4 benutzte Zugriffsart auf ein File, trägtdaher die Bezeichnung sequentieller Zugriff (engl. SequentialAccess). Die direkte Anwahl eines beliebigen Records ist imsequentiellen Zugriff nicht möglich.
CP/M 2.2 bietet daher mit dem direkten Zugriff (engl. RandomAccess) eine weitere Zugriffsart, mit der jeder Record einesFiles direkt erreicht werden kann.
Beim Random Access wird über zusätzliche Stellen im FCB eineabsolute Recördnummer zwischen 0 und 65535 dem BDOS über-geben.
Zur Aufnahme der Recördnummer beim Random Access, wird derFCB ab der Position 33 um die 3 Bytes RO, R1 und R2 er-weitert .RO und R1 enthalten die 16-Bit Recördnummer mit dem nieder-wertigen Byte in RO. R2 dient bei der Umrechnung zwischen SRNund RRN der Kennung eines Überlaufs und sollte immer auf Nullgesetzt werden.
Das BDOS berechnet aus dieser 'Random Record Number' (RRN)die 'Sequential Record Number1 (SRN), bestehend aus Extend-gruppe, Extend und Recördnummer.
21
Datenformate
Zwischen der Random Record Nummer und der SequentialNummer besteht folgender Zusammenhang:
Record
RRN -> SRN:
RRN - EG * 32 * 128 + EX * 128 + CR
SRN -> RRN:
EG - RRN / 4096 - RRN / (32 * 128)
EX - (RRN / 128) modulo 32
CR - RRN modulo 128
r - *•»!>--• •*•*» V
22
•s t Diskettenparameter
Der Disk Parameter Header
Das CP/M 2.2 erlaubt den Anschluß von bis zu 16 Laufwerkenunterschiedlicher Kapazität. Die zu jedem Laufwerk gehörendenParameter werden vom BIOS verwaltet und dem BDOS zur Verfü-gung gestellt.
Bei der Anwahl eines Laufwerks über das BIOSf erhält das BDOSdie Adresse eines Datenbereiches mit der Bezeichnung DPH. DPHist die Abkürzung für Disk Parameter Header, was soviel wie1 Disketten-Parameter-Anfang' bedeutet.
Der DPH ist der 'Anfang1 der Diskettenparameter und enthält,neben Daten, noch Verweise zu weiteren Tabellen.
Ein DPH umfasst 8 Einträge zu je 16 Bit und hat folgendeStruktur:
l XLT ! NHDE • CLTK ! FSCT l DIRBUF ! DPB • CSV • ALV l
Byte 0/1 2/3
mit
XLT
NHDE
CLTK
FSCT
DIRBUF
DPB
CSV
ALV
4/5 6/7 8/9 A/B C/D E/F
Adresse der Sektor-Verschränkungs-Tabelle(engl. X-lation Table)
Nummer des letzten belegten Eintrags in derDirectory der Diskette +1(engl. Number of Highest Directory Entry)
Aktuelle (zuletzt angewählte) logische Spur-nummer des Laufwerks(engl. Current Logical TracK)
Absolute (logische) Recordnummer des erstenRecords der aktuellen Spur(engl. First Sector of Current Track)
Adresse eines 128-Byte Buffers für Directory-Operationen(engl. DIRectory BUFfer)
Adresse des Disk Parameter Blocks(engl. Disk Parameter Block)
Adresse des Prüfsummenvektors(engl. Check Sum Vector)
Adresse des Belegungsvektors(engl. ALlocation Vector)
23
l
Diskettenparameter
Nur NHDE, CLTK und FSCT sind wirkliche Daten, alle anderenWerte sind Verweise auf weitere Tabellen.
Die Sektor-Verschränkungs-Tabelle (XLT) dient zur Umrechnungvon logischen zu physikalischen Sektornummern einer Spur. DieLänge dieser Tabelle entspricht der Anzahl logischer Sektorendie im DPB (s.u.) definiert sind.
24
NHDE ist die Nummer des höchsten belegten Directory-Ein- !trags+1 und dient der Geschwindigkeitserhöhung bei Directory- 'Zugriffen. |NHDE wird jeweils beim Einloggen eines Laufwerks und beim !Loschen oder Neuanlegen eines Eintrages neu berechnet. Die ]Berechnung der Prüfsumme und das Suchen eines Eintrages, Jbleibt im BDOS auf den so abgegrenzten Directory-Bereich «beschränkt. 1
CLTK und FSCT dienen dem BDOS der schnelleren Berechnung deranzuwählenden Spur- und Sektornummer bei einem Diskettenzu- \griff.Das BDOS berechnet aus Block- und Recordnummer des FCB eineabsolute logische Sektornummer dc^r Diskette. Mit der Anzahl
.-,,-.: >,--,. von logischen Sektoren pro Spur (siehe DPB) kann daraus dieSpur- und Sektornummer durch Division bestimmt werden. Daeine Division jedoch sehr zeitaufwendig ist, wird diese Rech-nung im BDOS auf eine wiederholte Subtraktion zurückgeführt.Von der absoluten Sektornummer wird solarige die Anzahl der \Sektoren pro Spur abgezogen, bis das Ergebnis negativ wird. 'Die Anzahl der durchgeführten Subtraktionen ist dann genaudie (logische) Spurnummer. !Durch Mitführen der zuletzt angewählten Spurnummer (CLTK) undder absoluten Recordnummer des ersten Records dieser Spur(FSCT), wird diese Rechnung im BDOS noch beschleunigt.
Das BDOS vergleicht die neue anzuwählende absolute Sektor-nummer immer mit FSCT. Ist die neue Sektornummer kleiner, sowird solange die Spurnummer CLTK dekrementiert und von FSCTdie Anzahl von Sektoren pro Spur abgezogen, bis die Sektor-nummer wieder größer als FSCT ist.In einer zweiten Schleife wird danach das Gleiche mit umge-kehrten Vorzeichen wiederholt: Es wird CLTK erhöht und zuFSCT die Anzahl der Sektoren pro Spur addiert, bis die anzu-wählende absolute Sektornummer wieder kleiner als FSCT ist.
IIIDieses 'Herantasten' an die Spurnummer beschleunigt die Be-rechnung der Spurnummer ganz erheblich, da auf eine Divisionverzichtet werden kann.Aus der Differenz der absoluten Sektornummer und des neuenFSCT-Wertes berechnet das BDOS dann noch die logische Sektor-nummer innerhalb der Spur.
DIRBUF ist die Adresse eines 128-Byte Puffers für Directory-Operationen. Alle Laufwerke können den selben DIRBUF be-nutzen, da das BDOS den Inhalt des DIRBUF bei einem Lauf-
l
Diskettenparameter
werkswechsel verwirft.
Der Disk Parameter Block (DPB) ist ziemlich komplex und wirdim nächsten Abschnitt getrennt besprochen. Mehrere DPH könnenauf ein und denselben DPB verweisen.
Im CSV sind die Prüfsummen (engl. Checksum) der einzelnenDirectory-Records gespeichert.Pro Directory-Record ist im CSV ein Byte vorhanden, daß dieQuersumme aller 128 Bytes des entsprechenden Records enthält.Vor der Änderung eines Directory-Records wird seine Quersummebestimmt und mit der im CSV gespeicherten Quersumme ver-glichen. Bei einer Abweichung sperrt das BDOS alle weiterenSchreibzugriffe auf dieses Laufwerk. Näheres dazu wurde be-reits im Zusammenhang mit dem Warmstart beschrieben.
Der Allocation Vektor (ALV) bildet die Belegungstabelle (bes-ser: Belegungsvektor) der Diskette.Aus dem Belegungsvektor kann das BDOS ersehen, welche Blockeauf der Diskette noch frei und welche belegt sind. Aus diesemVektor holt auch das STAT-Programm seine Information über dennoch verfügbaren Platz auf der Diskette.Die Bezeichnung 'Vektor1 deutet beim ALV auf die bitweiseSpeicherung hin. Für jeden Block der Diskette ist im ALV einBit vorhanden, daß entsprechend auf 0 (Block frei) oder 1(Block belegt) gesetzt wird.Die Zuordnung der Blöcke zu den Bits geschieht in abstei-gender Bitnummernfolge (höchstes Bit eines Bytes zuerst) undaufsteigender Bytefolge (erstes Byte des ALV zuerst).
Die Position eines zu einem Block gehörenden Bits, läßt sichsehr einfach berechnen:Die Blocknummer geteilt durch 8 ergibt die Position des Bytesinnerhalb des ALV; der Divisionsrest die Nummer des Bitsinnerhalb des ALV, wobei 0 das höchst- und 7 das nieder-wertigste Bit bezeichnet.
25
l
Diskettenparameter
Der Disk Parameter Block
Der Disk Parameter Block (DPB) beinhaltet alle Parameter, dieGröße and Aufteilung der Diskette beschreiben, insbesonderedie Anzahl der logischen Sektoren pro Spur, die Blockgröße,die Anzahl der Blocks auf der Diskette und die Größe derDirectory.
Ein DPB umfasst 15 Bytes in folgender Aufteilung:
SPT l
0/116
BSH
28
1 BLM
38
1 EXM 1
48
DSM 1
5/616
DRM
7/816
1 ALO
98
1 AL1
A8
1 CKS
B/C16
1 OFF
D/E16
(Die erste Zahlenreihe gibt die Position des Parameters innerhalb des DPB an und die zweite, ob es sich um einen 8oder 16-Bit Wert handelt.)
mit
• . .J . 47*. • •-••> L V
+-.. '-< . *,».». •-*-•> V
SPT
BSH
BLM
EXM
DSM
DRM
ALO
AL1
CKS
OFF
....,,. Anzahl der logischen Sektoren pro Spur(engl. Sectors Per Track)
2-er Exponent der Blockgröße(engl. Block SHift factor)
Anzahl von Records pro Block -1(engl. Block Length Mask)
Anzahl der Extends pro Eintrag -1(engl. Extend Mask)
Höchste Blocknummer der Diskette(engl. Data Storage Maximum)
Höchste Eintragnummer in der Directory(engl. DiRectory Maximum)
Erstes Byte des ALV(engl. Allocation Vector byte 0)
Zweites Byte des ALV(engl. Allocation Vector byte 1)
Anzahl der zu prüfenden Directory-Records(engl. ChecK vector Size)
Anzahl der reservierten Spuren am Anfangder Diskette(engl. track OFFset)
26
«v f Diskettenparameter
Die Verwendung des SPT-Wertes wurde bereits im letzten Ab-schnitt beschrieben. SPT entspricht auch der Länge der Sek-tor-Verschränkungs-Tabelle (XLT).
BSH und BLM beinhalten beide die Blocklänge BLS (engl. BLockSize). Durch diese 'doppelte' Angabe der Blocklänge werdenbestimmte BDOS-interne Rechenoperationen vereinfacht.
Zwischen der Blocklänge in Bytes undund BLM gilt folgender Zusammenhang:
den beiden Werten BSH
BLS
102420484096819216384
BSH
34567
BLM
71 53163
1 27
kurz
BLS 128 * 2~BSH - 128 * (BLM+1)
In EXM wird die Anzahl von Extends pro Directory-Eintragdefiniert.EXM ist abhängig von der Blockgröße und der Anzahl der Blöckepro Diskette. Je nachdem, ob weniger als 256 Blöcke (8-BitBlocknummern) oder mehr als 255 Blöcke (16-Bit Blocknummern)definiert sind, gibt es für EXM jeweils zwei Möglichkeiten:(Die erste EXM-Spalte gibt die Werte für 8-Bit Blocknummern,die zweite für 16-Bit Blocknummern an.)
-,. .„ „ ,.- , BLS ,..„. .,,«„ EXM
10242048409681 9216384
0137
15
0137
DSM enthält die Anzahl von Blöcken pro Diskette -1 bzw. diehöchste Blocknummer der Diskette.Die Gesamtkapazität der Diskette in Bytes ergibt sich aus demProdukt von BLS und (DSH+1); für den Allocation Vector müssen(DSM / 8) + 1 Bytes reserviert werden.
Rein theoretisch ist zwar eine Maximalkapazität von einemGigabyte (65536 Blöcke a 16 kbyte) denkbar, diese ist aberdurch die Verwaltung der Recordnummern im 16-Bit Format auf65536 Records, also 8 Megabyte (65536 * 128 Bytes) be-schränkt.
27
Diskettenparameter
DRM+1 ist die Anzahl der Directory-Einträge der Diskette. Dadie Eintragsnummern - genauso wie die Blocknummern - vonNull an gezählt werden, enthält DRM den um eins vermindertenWert.
ALO und AL1 bilden die ersten beiden Bytes des AllocationVectors und müssen daher, wie der ALV, als Bitvektor gesehenwerden.Für jeden als Directory-Bereich reservierten Block der Dis-kette, muß das entsprechende Bit in diesem Vektor gesetztwerden. Das höchste Bit von ALO entspricht dem ersten Blockder Diskette (Block Nummer 0) und das letzte Bit in AL1 demsechzehnten Block {Block Nummer 15). Da ALO und AL1 nur einen16-Bit Vektor bilden, ist die Anzahl der maximal möglichenDirectory-Blöcke auf 16 beschränkt.
CKS kennzeichnet die Länge des Prüfsummen-Vektors (CSV) unddamit die Anzahl der zu prüfenden Directory-Records die sichaus der Beziehung CKS - (DRM + 1) / 4 ergibt.Falls eine Prüfung der Directory nicht erwünscht oder, wiez.B. bei Festplattenlaufwerken, nicht notwendig ist, kannCKS auch Null sein.
OFF ist die Anzahl der reservierten Spuren auf der Diskette.Dieser Wert ist für das BDOS unerheblich, wird aber vor demSetzen der physikalischen Spurnummer zur errechneten lo-gischen Spurnummer (CLTK) addiert.
28
BDOS-Funktionen
Aufruf von BDOS-Funktionen
Alle BDOS-Funktionen werden über den Sprungbefehl zum BDOS ander Adresse BOOT+0005H erreicht. Dadurch ist, unabhängig vonder tatsächlichen Lage des BDOS im Speicher, die Betriebs-system-Schnittstelle für alle CP/M-Rechner identisch.
Ein Programm lädt die gewünschte Funktionsnummer in das C-Register des Prozessors und führt danach ein 'CALL1 nachBOOT+0005H aus. 8-Bit Funktionsparameter werden im E-Regis-ter, 16-Bit Parameter im Registerpaar DE übergeben. Das BDOSführt daraufhin die gewünschte Funktion aus und gibt einen 8-(im Register A) oder 16-Bit Funktionswert (im RegisterpaarHL) zurück.
Das BDOS im CP/M 2.2 bietet insgesamt 39 verschiedene Funk-tionen zur Zeichen- und Dateibearbeitung, die im folgendenbeschrieben werden. Neben der Funktionsnummer und der eng-lischen und deutschen Funktionsbezeichnung, ist auch dieStartadresse der jeweiligen Funktion im BDOS-Listing ange-geben.
'!:' bezeichnet die notwendige Registerbelegung beim Aufrufdes BDOS, 'O:' die vom BDOS zurückgelieferten Registerwerte.
Nummer: 0
Bezeichnung: System ResetWarmstart
Adresse: BIOS+0003H* « l 4l ° l .''"..'••
i: c = OOH
o:
Ausgeführte Funktion:
Direkter Sprung zur Warmstartroutine im BIOS. Der Warmstartlädt den CCP und das BDOS neu in den Speicher und übergibtdie Kontrolle an den CCP. Die Funktion 0 entspricht einemSprung zur Adresse BOOT.
29
BDOS-Funktionen
Nummer:
Bezeichnung
Adresse:
I:
O:
1
Console InputConsoleneingabe
02C8H
C - 01H
A - Zeichen von der Console
Ausgeführte Funktion:
Console Input holt das nächste Zeichen von der Console undsendet darstellbare Zeichen über die Consolenausgabe als Echozurück.Die Steuerzeichen 'Carriage Return1 (ASCII ODH), 'Line Feed1
(ASCII OAH) und 'Backspace1 (ASCII 08H) werden ebenfallsausgegeben. Das 'Tab1-Zeichen (ASCII 09H) erzeugt auf derAusgabe soviele Leerzeichen wie zur Erreichung der nächsten,durch 8 teilbaren Spaltenposition (Tabulator-Position) not-wendig sind.Bei Erkennung von CTRL-S (ASCII 13H) wartet Console Input aufein weiteres Zeichen und halt dadurch die Verarbeitung an.CTRL-C (ASCII 03H) führt zu einem direkten Sprung nach BOOT,was im allgemeinen einen Warmstart auslöst.Die Console Input Funktion ist erst beendet, wenn tatsächlichein Zeichen von der Console erkannt wurde.
Nummer:
Bezeichnung:
Adresse:
Console OutputConsolenausgabe
01 90H
i:
o:
C = 02HE = ASCII-Wert
Ausgeführte Funktion:
Der ASCII-Wert vom Register E wird zur Console ausgegeben unddie Consoleneingabe überprüft. Vor der eigentlichen Zeichen-ausgabe wird der Consolenstatus über die BDOS-Funktion 11überprüft. Alle dort beschriebenen Verhaltensweisen geltendaher auch für die Consolenausgabe. Die Behandlung des 'Tab'-Zeichens ist wie in Funktion 1 .
30
„*• *
BDOS -Funktionen*
Nummer: 3
Bezeichnung: Reader Input1 Reader ' -Eingabe
Adresse: 02CEH
i: C - 03H
O: A - Zeichen vom ' Reader ' -Kanalk '
Ausgeführte Funktion:
Reader Input holt das nächste Zeichen vom 'Reader ' -Kanal ,stellt es aber nicht auf der Console dar.Das BDOS führt keine weitere Zeichenbehandlung durch, sondernbenutzt direkt die entsprechende BIOS-Funktion.
Nummer: 4•*•-•••Bezeichnung: Punch Output
1 Punch'-Ausgabe
Adresse: BIOS + 0012H
I: C - 04HE = ASCII-Wert
O:
Ausgeführte Funktion:
Das BDOS verzweigt direkt zur entsprechenden BIOS-Funktion,die das Zeichen zum 'Reader'-Kanal ausgibt.
Nummer: 5
Bezeichnung: List OutputDruckerausgäbe
Adresse: BIOS + OOOFH
i: C = 05HE = ASCII-Wert
o:
Ausgeführte Funktion:
Das BDOS verzweigt direkt zur entsprechenden BIOS-Funktion,die das Zeichen zum 'List'-Kanal ausgibt. Der 'List'-Kanalist im CP/M als Druckerausgabe definiert.
31
BDOS-Funktionen
Nummer:
Bezeichnung:
Adresse:
Direct Console I/ODirekte Consolenein/ausgabe
02D4H
O;
CEEE
AAA
- 06HOFFH für ConsoleneingabeOFEH für Consolen-Status prüfenASCII Zeichen zur Consolenausgabe sonst
Zeichen von der Console (falls E - OFFH)Consolen-Status (falls E - OFEH)Undefiniert sonst
Ausgeführte Funktion:
Über die direkte Consolenein/ausgabe kann die Console unterUmgehung des BDOS erreicht werden. Alle Sonderbehandlungenvon Zeichen, wie sie das BDOS bei den Funktionen 1 und 2vornimmt, werden unterdrückt. Die direkte Consolenein/ausgabebenutzt direkt die entsprechenden BIOS-Funktionen.
Nummer:
Bezeichnung:
Adresse:
i:
Get I/O ByteI/O Byte holen
02EDH
C = 07H
O: A = I/O-Byte von der Adresse BOOT+0004H
Ausgeführte Funktion:
Das BDOS gibt den^Inhalt der Speicherstelle BOOT-f0004H im A-Register zurück. Über das I/O-Byte kann im BIOS eine weitereAufschlüsselung der Ein/Ausgabekanäle vorgenommen werden,dies hat jedoch keinen Einfluss auf das BDOS.
32
BDOS-Funktionen
Nummer: 8
Bezeichnung: Set I/O ByteI/O Byte setzen
Adresse: ' 02F3H."U '-(•,'-
* - f f;
I-Ir" C - 08HE - I/O-Byte
O: *
Ausgeführte Funktion:
Der im E-Register übergebene Wert wird in der SpeicherstelleBOOT+0004H abgelegt. Damit kann ein Programm die Zuordnungder Ein/Ausgabekanäle beeinflussen, falls das I/O-Byte vomBIOS beachtet wird.
Nummer: 9
Bezeichnung: Print StringZeichenkette ausgeben
Adresse: 02F8H
It C - 09HDE -> Zeichenkette
6:Ausgeführte Funktion:
Die einzelnen Zeichen der Zeichenkette werden über die BDOS-Funktion 2 zur Console ausgegeben. Die weitere Zeichenbe-handlung ist daher identisch mit der Consolenausgabe. DasZeichen '$' zeigt das Ende der Zeichenkette an und wird nichtausgegeben.
Nummer: 10
Bezeichnung: Read Console BufferZeile von der Console einlesen
Adresse: 01E1H
i: c - OAHDE -> Zeilenbuffer
Öl Zeilenbuffer gefüllt mit den eingegebenenZeichen
33
BDOS-Funktionen
'
Ausgeführte Funktion:
Alle folgende Zeichen von der Consoleneingabe werden in denZeilenpuffer übernommen und über die Consolenausgabe darge-stellt.Die Eingabe ist beendet, wenn entweder eines der Zeichen'Carriage Return1 (ASCII ODH) oder 'Line Feed1 (ASCII OAH)erkannt wird oder das Ende des Buffers erreicht ist.Die Bufferlänge erhält das BDOS im ersten Byte des Zeilenbuf-fers mitgeteilt. Nach Beendigung der Funktion steht im zwei-ten Byte die Anzahl der tatsächlich eingegebenen Zeichengefolgt von den eigentlichen Zeichen. Die Bufferlänge istdamit immer um zwei Bytes größer als die maximale Zeilen-länge.Während der Eingabe werden vom BDOS verschiedene Steuerzei-chen zur Editierung der Zeile erkannt:
CTRL-C (ASCII 03H)
CTRL-E (ASCII 05H)
CTRL-H (ASCII 08H)
CTRL-J (ASCII OAH)
CTRL-M (ASCII ODH)CTRL-P (ASCII 10H)
CTRL-R (ASCII 12H)
CTRL-U (ASCII 15H)
CTRL-X (ASCII 18H)
DEL (ASCII 7FH)
führt zu einem Warmstart, falls es alserstes Zeichen eingegeben wird,beginnt eine neue Zeile auf der Consolen-ausgabe, ohne jedoch den Zeilenbuffer zuändern.löscht das jeweils letzte Zeichen sowohlim Buffer als auch auf der Consolenausgabe,beendet die Zeileneingabe und sendet ein'Carriage Return1 (ASCII ODH) zur Conso-lenausgabe.hat die selbe Wirkung wie CTRL-Jschaltet die parallele Druckerausgabe zurConsolenausgabe (Protokollfunktion) einoder aus.beginnt eine neue Ausgabezeile und zeigtdie bisher eingegebene Bufferzeile noch-mals an.beginnt eine neue Ausgabezeile und startetdie gesamte Zeileneingabe neu. Die bisherausgegebenen Zeichen werden nicht ge-löscht.löscht die bisher eingegebenen Zeichensowohl im Buffer als auch auf der Conso-lenausgabe. Die Zeileneingabe wird darauf-hin neu begonnen.löscht das jeweils letzte Zeichen desBuffers und gibt es nochmals auf der Con-sole aus.
« '
34
BDOS-Funktionen
Nummer: 11
Bezeichnung: Get Console StatusConsolenstatus testen
Adresse: 02FEH
I; C - OBH
O: A - FFH, falls ein Zeichen von der Console an-steht
- OOH sonst
Ausgeführte Funktion:
Es wird geprüft, ob ein Zeichen von der Console zur Eingabeansteht. Die Consolenstatus-Funktion speichert ein anstehen-des Zeichen zwischen und gibt es beim nächsten Consolenein-gabe-Aufruf als Zeichen zurück.Das Zeichen CTRL-S wird von dieser Funktion erkannt, diedaraufhin auf ein weiteres Zeichen wartet. CTRL-C bewirkteinen direkten Sprung nach BOOT, was im allgemeinen zu einemWarmstart führt.Falls ein anstehendes Zeichen nicht 'abgeholt' wird, gibt dieConsolenstatus-Funktion immer FFH zurück, ohne den Status derConsole wirklich zu testen. In diesem Fall werden die Steuer-zeichen CTRL-S und CTRL-C nicht mehr erkannt l
Nummer: 12»
Bezeichnung: Return Version NumberCP/M Versionsnummer zurückmelden
* * *
Adresse: OC7EH
i: c = OCH
O: HL = 0022H (bei CP/M 2.2)
Ausgeführte Funktion:
Über die BDOS-Funktion 12 können Programme auf eine bestimmteCP/M Version angepasst werden. Im H-Register wird für CP/Mder Wert OOH, für MP/M (multi-tasking CP/M) der Wert 01Hzurückgegeben. Das L-Register bezeichnet dann die genaueVersionsnummer. L = OOH bezeichnet alle Versionen vor CP/M2.0, die Werte 20H, 21 H, 22H usw. die entsprechenden CP/MVersionen 2.0. 2.1, 2.2 usw.
35
BDOS-Funktionen
Nummer:
Bezeichnung:
Adresse:
I:
0:
13
Reset Disk SystemBDOS in den Ausgangszustand bringen
OC83H
C - ODH
A - FFH, falls auf dem Laufwerk A:, Userbereich 0 ein Filenamen mit '$' beginnt.
A - OOH sonst
Ausgeführte Funktion:
Diese Funktion wird dazu benutzt, das BDOS in einen kontrol-lierten Ausgangszustand zu bringen. Die Schreiberlaubnis wirdfür alle Laufwerke freigegeben und das Laufwerk A: angewählt.Die DMA-Adresse wird auf den Standardwert BOOT+0080H gesetzt.Die Anwahl von Laufwerk A: wird im Zusammenhang mit demzurückgegebenen Parameter vom CCP benutzt. Falls auf demLaufwerk A:, Userbereich 0 ein Filenamen mit '$' beginnt, soversucht der CCP das Submit-File '$$$.306' zu öffnen und dennächsten Befehl aus diesem File zu lesen.
Nummer:
Bezeichnung:
Adresse:
l:
14
Select DiskLaufwerk anwählen
OC45H
C = OEHE = Nummer des anzuwählenden Laufwerks
= OOH für Laufwerk A:• • •
= OFH für Laufwerk P:
0: ,„..* , ,, -r.,., _ , ,-,..., -„-K
Ausgeführte Funktion:
Das gewählte Laufwerk v/ird als Bezugslaufwerk für alle weite-ren Dateioperationen festgelegt. Falls das Laufwerk seit demletzten Warmstart noch nicht angewählt war, liest das BDOSdie Directory und initialisiert die Belegungs- und Prüfsum-mentabelle .Das BDOS prüft vor Aufruf der BIOS-Funktion zur Laufwerksan-wahl, die im Register E übergebene Laufwerksnummer nicht aufihren Wert.Das BIOS gibt dem BDOS die Adresse des zum Laufwerk gehören-den DPH (falls unter der Nummer ein Laufwerk existiert) oderden Wert 0000h zurück (falls kein Laufwerk existiert bzw. der
36
l
i
BDOS-Funktionen
Wert > OFH war).Im Fehlerfall meldet das BDOS einen 'Select Err' und brichtdie Funktion über einen Warmstart ab.
Nummer:
Bezeichnung
Adresse:
I:
O:' 4b( »> A X *> V *»
1 5
Open FileFile öffnen
OC9CH
C - OFHDE -> FCB
A - Fehlercode^ _ - OFFH, falls das File nicht existiert
Directory-Code des geöffneten Eintragssonst
Ausgeführte Funktion:
Das in der ersten FCB-Position angegebene Laufwerk (0aktuelles Laufwerk, 1 - Laufwerk A:,..., 16 - Laufwerk P:)wird angewählt und ein auf den FCB passender Eintrag gesucht.Die Suche nach dem passenden Eintrags und auch die Berechnungdes Directory-Code geschieht über die BDOS-Funktion 17'Search for First1.Der gefundene Directory-Eintrag wird komplett in den FCBübertragen, der damit nach dem Öffnen alle Directory-Infor-mationen enthält.Durch Angabe einer Extendnummer in der entprechenden FCB-Position, kann direkt der Eintrag geöffnet werden, der dengewünschten Extend abdeckt. Die direkte Anwahl einer Extend-gruppen ist nicht möglich, es wird immer ein Extend in derExtendgruppe 0 geöffnet.
Nummer:
Bezeichnung
Adresse:
i:
o:
1 6
Close FileFile schliessen
OCA5H
C* —
DE ->10HFCB
A = FehlercodeFFH, falls das File nicht existiertoder der FCB fehlerhafte Daten enthaltDirectory-Code des geschlossenen Ein-trags sonst
37
BDOS -Funktionen
Ausgeführte Funktion:
Über die BDOS-Funktion 17 ('Search for First1) wird ein aufden FCB passender Eintrag gesucht und die Daten des FCB indiesen Eintrag übernommen. Falls das über die FCB-Position 0angewählte Laufwerk schreibgeschütz ist, wird die Funktionmit einem 'R/O '-Fehler abgebrochen.Ist das File seit dem Öffnen unverändert ('NA'-Flag gesetzt),so wird die 'Close File ' -Funktion sofort beendet und der WertOOH zurükgegeben.Vor dem Zurückschreiben des Eintrags, wird die Blocktabelledes gefundenen Eintrags mit der Blocktabelle des FCB ver-glichen und die Blocktabellen einander angepasst. Differenzender Blocknummern dürfen nur bei jeweils unbelegten Tabellen-Einträgen auftreten.Da die ersten 32 Bytes des FCB in den Eintrag kopiert werden,ist die neue Länge des Files durch die Werte EX, EG und RC imFCB gegeben. Vor dem Schliessen eines Files muß die Record-position daher immer auf den letzten Record des Files ge-bracht werden.
Nummer: •- 17 • • " •-••••-' •- • •-••;** -»»-.y---.
Bezeichnung: Search for FirstErsten passenden Eintrag suchen
Adresse: OCABH
l: C - 1 1KDE -> FCB
O: A FehlercodeFFH, falls das File nicht existiertDirectory-Code des gefundenen Eintragssonst
Ausgeführte Funktion:
Das in der ersten FCB-Position angegebene Laufwerk wird an-gewählt und die Directory nach dem ersten, auf den FCB pas-senden Eintrag, durchsucht.Es werden dabei nur die Directory-Einträge beachtet, die imaktuellen Userbereich liegen und in den Positionen 1-14 mitde FCB übereinstimmen.Der Wert 3FH ('?') in einer der FCB-Positionen 1 bis 14 wirdals 'Joker1 gewertet und bei der Suche nach einem passendenEintrag nicht beachtet.Bei einem 'Joker' in der FCB-Position 0, gibt die Funktionden ersten Directory-Eintrag, ohne Beachtung seiner Daten,zurück. Diese Funktion ist zwar im allgemeinen nicht sinn-voll, kann aber im Zusammenhang mit der Funktion 'Search forNext1 (BDOS-Funktion 18) zur Erreichung aller Directory-Einträge benutzt werden.
38
fl-
BDOS-Funktionen
Aus Gründen der Kompatibilität mit der alten CP/M Version1.4, kopiert diese Funktion den Directory-Record, der den
l gefundenen Eintrag enthält, an die DMA-Adresse. Dadurch kön-nen aber auch Anwenderprogramme die Directory-Informationenauswerten und für eigene Zwecke nutzen.
Nummer:
Bezeichnung:
Adresse:
I:
o:
18
Search for NextNächsten passenden Eintrag suchen
OCC8H
C - 12H
A - FehlercodeFFH, falls kein weiterer Eintrag ge-funden v/erden konnte
- Directory-Code des nächsten gefundenenEintrags sonst
Ausgeführte Funktion:
Ausgehend vom letzten 'Search for First', wird der nächstepassende Eintrag gesucht. Die Angabe einer FCB-Adresse alsFunktionsparameter ist nicht nötig, da der FCB vom letzten'Search for First'-Aufruf benutzt wird. Der Directory-Record,der den gefundenen Eintrag enthält, wird zur aktuellen DMA-Adresse kopiert.Die Bezeichnungen 'erster' und 'nächster1 in den BDOS-Funk-tionen 17 und 18, beziehen sich immer auf die Nummer desEintrages in der Directory.
Nummer:
Bezeichnung:
Adresse:
i:
19
Delete FileFile löschen
OCD7H
C - 1 3HDE -> FCB
0: A Fehlercode= OOH, kein Fehler
FFH, falls kein passender Eintrag gefun-den wurde
Ausgeführte Funktion:
Beim Löschen eines Files, werden alle auf den FCB passendenEinträge aus der Directory gelöscht und die in der Blockta-
39
BDOS-Funktionen
belle des Eintrages verzeichneten Blöcke durch Änderung derBelegungstabelle freigegeben.Das Löschen eines Eintrages aus der Directory, geschiehtdurch Ersetzen der ersten Eintragsposition (üsernummer) mitdem Wert E5H. Alle v/eiteren Bytes des Eintrages bleibenunverändert.Dies hat den Vorteil, daß durch Wiedereinsetzen der Usernum-mer ein Eintrag wieder aktiviert werden kann. Beim Reakti-vieren ist jedoch zu beachten, daß manche der vormals beleg-ten Blöcke bereits wieder neu vergeben sein können.
Nummer:
Bezeichnung:
Adresse:
l:
20
Read SequentialSequentielles Lesen
OCEOH
C - 14HDE -> FCB
t -t '.fr* ' fc 'l •!*•'•* V
"•'•'• ' ~ • A - Fehlercode- OOH, kein Fehler
01H, Ende des Files erreichtFFH, falls zu dem File kein Directory-
Eintrag existiert
Ausgeführte Funktion:
Der durch die FCB-Werte CR, EX und EG definierte Record desFiles wird gelesen und die Recordposition im FCB um 1 erhöht.Beim Erreichen einer Extendgrenze wird der aktuelle Extendautomatisch geschlossen und der folgende Extend eröffnet.Falls der nächste Extend nicht mehr vom FCB abgedeckt ist,öffnet das BDOS auch einen neuen Eintrag. Der Fehlercode FFHwird zurückgegeben, wenn in diesem Fall der alte Eintragnicht mehr gefunden v/erden konnte.Vor dem Lesen eines Files muß über die BDOS-Funktion 26 'SetDMA Address' ein 128-Byte Speicherbereich zur Aufnahme desRecords definiert werden. Das BDOS erhöht nach einem sequen-tiellen Lesezugriff zwar die Recordposition im FCB, nichtaber die DMA-Adresse. Beim Lesen mehrerer Records in denSpeicher ist das Anwenderprogramm für die Anpassung der DMA-Adresse zuständig.
40
BDOS-Funktionen
Nummer: 21
Bezeichnung: Write SequentialSequentielles Schreiben
Adresse: OCE6H
l: • C - 15HDE -> FCB
T_
0: A Fehlercode- OOH, kein Fehler
01H, Fehler beim Diskzugriffoder falsche Recordnummer
- 02H, Diskette voll
Ausgeführte Funktion:
Aus dem zuletzt über 'Set DMA-Address* (BDOS-Funktion 26)definierten Speicherbereich, werden 128 Bytes in das angege-bene File geschrieben. Die exakte Recordposition ist durchdie Werte EG, EX und CR irn FCB bestimmt.Nach Abschluss der Fuktion wird die Recordposition um einserhöht und, bei Erreichen der Extendgrenze, ein neuer Extendoder sogar ein neuer Eintrag eröffnet.Dieses 'Vorgreifen' auf den nächsten Record führt allerdingsdazu, daß evtl. ein Block oder Eintrag zuviel belegt wird, dader neue Record erst beim folgenden Schreibzugriff mit Datengefüllt wird.Abhilfe bietet in diesem Fall nur der direkte Zugriff (RandomAccess), der diesen 'Vorgriff' unterdrückt.
Nummer: ' 22
Bezeichnung: Make FileNeues File erzeugen
Adresse: OCECH
i: C = 16HDE -> FCB
O: A FehlercodeFFH, falls die Directory voll ist
» Directory-Code des neuen Eintrages sonst'!?
Ausgeführte Funktion:
'Make File1 wird dazu benutzt, ein neues File zu erzeugen undzu öffnen, zu dem noch kein Directory-Eintrag vorliegt.Maßgebend für den neuen Eintrag sind nur die ersten 12 Bytesdes FCB, da alle weiteren Bytes automatisch auf 0 initiali-siert werden.
41
BDOS-Funktionen
Die 'Make File'-Funktion sucht den ersten freien Eintrag inder Directory, kopiert die 32 Bytes des FCB in den Eintragund schreibt ihn wieder zurück in die Directory.Falls im selben Userbereich bereits ein weiterer Eintrag mitdem gleichen Filenamen und Filetyp existiert, kann das BDOSzwischen beiden Einträgen nicht unterscheiden. Vor dem Er-zeugen eines neuen Files muß daher, z.B. durch vorherigenAufruf der 'Delete File'-Funktion, sichergestellt sein, daßder Filenamen und Filetyp nur einmal existiert.
Nummer:
Bezeichnung:
Adresse:
I:
O:
23
Rename FileFilenamen ändern
OCF5H
C -DE ->
A -
17HFCB (Alter und neuer Filenamen)
Fehlercode- OOH, kein Fehler- FFH, falls kein Eintrag mit dem alten
Filenamen gefunden wurde
Ausgeführte Funktion:
Die ersten 12 Bytes des über DE adressierten FCB geben denalten Filenamen und Filetyp an. Ab Position 17 muß der neueFilenamen und ab Position 25 der neue Filetyp folgen. Nichtbenutzte Stellen im Filenamen oder Filetyp müssen Leerzeichenenthalten.Das in der ersten FCB-Position angegebene Laufwerk wird se-lektiert und alle Einträge, die in Usernummer, Filename undFiletyp mit dem FCB übereinstimmen, mit dem neuen Filenamenzurückgeschrieben.
Nummer: "" "'
Bezeichnung:
Adresse:
24 ' „.%*• JSi
Return Login VectorLogin-Vektor zurückgeben
OCFEH
i:
o:
C = 18H
HL = Login-Vektor
Ausgeführte Funktion:
Der Login-Vektor ist ein 16-Bit Wert, dessen niederwertigstesBit dem Laufwerk A: und höchstwertigstes Bit dem Laufwerk P:
42
BDOS-Funktionen
entspricht. Eine '1' an einer der Bitpositionen zeigt an, daßdas entsprechenden Laufwerk seit dem letzten Warmstart schon-mal angewählt wurde. Aufgrund der Information des Login-Vektors, entscheidet das BDOS bei einer Laufwerksanwahl, obdie Belegungs- und Prüf Summentabelle neu erstellt v/erden muß.
Nummer:
Bezeichnung
Adresse:
l:
O: •""*"" '•-*"'"
25
Return Current DiskAktuelle Laufwerksnummer zurückgeben
OD04H
C - 19H
A - Laufwerksnummer *,--^-,t**,*0 für Laufwerk A:
• • •
- 15 für Laufwerk P:
Ausgeführte Funktion:
Die Nummer des zuletzt über die BDOS-Funktion 14 'SelectDisk1 angewählten Laufwerks, wird im A-Register zurückge-geben.
Nummer:
Bezeichnung:
,. *.
Adresse:
i:
o:
26
Set DMA AddressDMA-Adresse festlegen
ODOAH ..- ~.' ..
C = 1AHDE = DMA-Adresse
Ausgeführte Funktion:
Die im Registerpaar DE angegebene Adresse wird für alleweiteren Dateioperation als Anfangsadresse eines 1 28-ByteBuffers benutzt. Nach einem Warmstart oder der BDOS-Funktion13 'Reset Disk System1 ist die DMA-Adresse auf BOOT+0080Hfestgelegt.
j 43
BDOS-Funktionen
Nummer:
Bezeichnung:
Adresse:
I:
O:
27
Get Allocation AddressAdresse des Belegungsvektors (ALV) holen
OD11H
C - 1BH
HL -> ALV des aktuellen Laufwerks
Ausgeführte Funktion:
Die bei der Laufwerksanwahl im DPH angegebene Adresse desBelegungsvektors (ALV), wird dem aufrufenden Programm mitge-teilt. Aus dem ALV berechnet z.B. das STAT-Programm denverbleibenden Speicherplatz auf einer Diskette.
's-
Nummer :
Bezeichnung:
Adresse:
I:
28
Write Protect DiskLaufwerk schreibschützen
052CH
C - 1CH
o:
Ausgeführte Funktion:
Alle weiteren Schreibzugriff auf das aktuelle Laufwerk werdenunterbunden und führen zu der Meldung 'BDOS ERR on d: R/O1,wobei d: das Laufwerk bezeichnet. Diese Funktion wird auchBDOS-intern nach dem Erkennen einer PrüfSummendifferenz be-nutzt.
Nummer!
Bezeichnung:
Adresse:
i:
o:
29• A
Get Read/Only VectorR/O-Vektor holen
OD17H
1DH
HL = R/O-Vektor
Ausgeführte Funktion:
Der R/O-Vektor ist ein 16-Bit Wert und hat den selben Aufbauwie der Login-Vektor (siehe BDOS-Funktion 24, 'Return Login
44
BDOS-Funktionen
Vetor1). Ein gesetztes Bit in diesem Vektor,sprechende Laufwerk als schreibgeschützt aus.
weist das ent-
Nummer:
Bezeichnung
Adresse:
I:
0:
30
Set File AttributesFile Attribute setzen
OD1DH
C - 1EHDE -> FCB
A - Fehlercode- OOH, kein Fehler- FFH, falls das File nicht existiert
Ausgeführte Funktion:
Die ersten 1 2 Bytes des FCB v/erden in alle passenden Direc-tory-Einträge kopiert und die Einträge wieder zurückgeschrie-ben. Damit können die Fileattribute (höchste Bits im Filetyp)eines Files geändert v/erden.
Nummer:
Bezeichnung
Adresse:
* * *r *•
i:
o:
31
Get Disk Parameter AddressAdresse des DPB holen
OD26H
C - 1FH
HL -> DPB des aktuellen Laufwerks
Ausgeführte Funktion:
Die bei der Laufwerksanwahl im DPH angegebene Adresse desDisk Parameter Blocks (DPB) wird dem aufrufenden Programmmitgeteilt.Aus dem DPB können alle laufwerksspezifischen Parameter ent-nommen werden. Aus der dort angegebenen Blockgröße und derAnzahl der Blöcke berechnet z.b. das STAT-Programm die Disk-ettenkapazität in Bytes. Zusammen mit dem Belegungsvektor(ALV) kann so auch der verbleibende Platz in Bytes bestimmtwerden.Spezielle Programme können den DPB auch ändern und so einedynamische Anpassung an verschiedene Diskettenformate er-reichen.
45
BDOS-Funktionen
Nummer:
Bezeichnung:
Adresse:
32
Set/Get User CodeUsernummer holen/setzen
OD2DH
O;
C -E -E -
A -
20HFFHUsernummer
(Holen der Usernummer)(Setzen der Usernummer)
aktuelle Usernummer (falls E - FFH)OOH sonst
entwederaktuellen
Ausgeführte Funktion:
Abhängig vom im Register E übergebenen Wert, wirdein neuer Userbereich gewählt oder die Nummer desBereichs zurückgegeben.Beim Setzen der Usernummer, wird der Wert im E-Registermodulo 32 genommen und somit der Wertebereich auf 0 bis 31begrenzt.
Nummer:
Bezeichnung:
Adresse:
33
Read RandomDirekter Lesezugriff
OD41H
C =DE ->
21HFCB mit Random Record Nummer (RRN)
O: A = Fehlercode= 0= 1= 3
= "4= 6
Ausgeführte Funktion:
kein Fehlerder Record enthalt noch keineder zuletzt angewählte Extendnicht geschlossen werdender Record liegt 'hinter* demdie gewählte Recordnummer istals 65535
Datenkann
Fileendegrößer
Durch den direkten Lesezugriff kann ein beliebiger Recordeines Files direkt gelesen werden.Die gewünschte Recordnummer wird als 16-Bit Wert in zusätz-lichen FCB-Positionen ROund R1 (Positionen 34,Ein drittes Byte an derterung der Recordnummerjedoch nicht benutzt. Enthält diesesNull verschiedenen Wert, so wird der
(Position 33, niederwertiges Byte)höherwertiges Byte) angegeben.Position 35 (R2) ist zwar zur Erwei-auf 24-Bit definiert, im CP/M 2.2
Byte jedoch einen vonFehlercode 6 'Seek past
46
BDOS-Funktionen
physical end of disk' zurückgegeben.Die angegebene Recordnummer wird in die entsprechenden WerteExtendgruppe (EG), Extend (EX) und Recordnummer im Extend(CR) umgerechnet und ein sequentieller Lesezugriff ausge-führt. Mach Beendigung der "Read Random?-Funktion sind dieFCB-Positionen EG, EX und CR daher immer auf den folgendenRecord aktualisiert.Die angegebene Random Record Nummer wird vom BDOS nichtbeeinflusst, wodurch ein folgender Zugriff wieder den selbenRecord behandelt.Vor dem Lesezugriff wird ein evtl. notwendiger neuer Extendautomatisch geöffnet und der alte Extend geschlossen. DerFehlercode 1 tritt dann auf, wenn der neue Extend zwar exis-tiert, die neue Recordposition aber über dem höchsten Recorddieses Extends liegt.Die Fehlercode 2 und 5 werden beim direkten Lesezugriff nichtzurückgegeben.
Nummer:
Bezeichnung
Adresse:
I:
34
Write RandomDirekter Schreibzugriff
OD47H
CDE
A =
22H-> FCB mit Random Record Nummer (RRN)
Fehlercode= 0, kein Fehler= 2, Diskette voll
.. - . , -v ..,-. = 3, der zuletzt angewählte Extend kannnicht geschlossen v/erden
= 5, ein neuer Eintrag konnte nicht geöffnetwerden
= 6, die gewählte Recordnummer ist größerals 65535
Ausgeführte Funktion:
Für die 'Write Random'-Funktion gilt sinngemäß das selbe wiefür die 'Read Random'-Funktion. Hit dem direkten Schreibzu-griff kann ein File jedoch auch vergrößert werden, weshalbdie Fehlercodes 1 und 4 nicht zurückgegeben werden.Falls zur Erweiterung des Files ein neuer Eintrag erforder-lich und die Directory voll ist, wird der Fehlercode 5 zu-rückgegeben.
47
BDOS-Funktionen
Nummer:
Bezeichnung:
Adresse:
35
Compute File SizeFilelänge bestimmen
OD4DH
I: C -DE ->
23HFCB
O: RO, R1 und R2 im FCB gesetzt
Ausgeführte Funktion:
Diese Funktion durchsucht alle passenden Einträge und be-rechnet die Recordnummer des letzten Records im jeweiligenEintrag. Die höchste, so gefundene Recordnummer bestimmt dieFilelänge und wird als Random Record Nummer in die PositionenRO, R1 und R2 des FCB eingetragen.Durch einen nachfolgenden direkten Lesezugriff können Ex-tendgruppe, Extend und Recornummer im FCB gesetzt und, überweitere sequentielle Schreibzugriffe, Records an das Fileangehängt v/erden.
Nummer; 36
Bezeichnung: Set Random RecordRandom Record Nummer bestimmen
Adresse: OCOEH
i: c =DE ->
24HFCB
o: RO, R1 und R2 im FCB gesetzt
Ausgeführte Funktion:
Aus der sequentiellen Recordposition im FCB (Extendgruppe,Extend und Record) wird die Random Record Nummer berechnetund im FCB eingesetzt. Dadurch kann ein 'Umschalten' vomsequentiellen in den direkten Zugriff erreicht werden.Das 'Zurückschalten' erfolgt bei jedem weiteren direktenZugriff, der aus der Random Record Nummer wieder die ent-sprechende Extendgruppennummer, Extendnummer und Recordnummerberechnet und in den FCB einsetzt.
48
BDOS-Funktionen
Nummer:
Bezeichnung
Adresse:
l:
0:
37
Reset DriveLaufwerk zurücksetzen
OD53H
C - 25HDE - Disk Vektor
A - OOH
Ausgeführte Funktion:
Durch das Zurücksetzen eines Laufwerkes, wird das ent-sprechende Bit aus dem Login- und R/O-Vektor gelöscht undbeim nächsten Zugriff auf dieses Laufwerk, der Belegungs-vektor und die PrüfSummentabelle neu errechnet.Der im Registerpaar DE übergebene Vektor hat den selbenAufbau wie der Login- und der R/O-Vektor, bezeichnet aber diezurückzusetzenden Laufwerke.Sinn dieser Funktion ist es, einen vom Anwenderprogramm kon-trollierten Diskettenwechsel zu ermöglichen.
Nummer:
Bezeichnung
Adresse:
i:
o:
38
C = 26H
A = OOH
Ausgeführte Funktion
keine Funktion
Nummer:
Bezeichnung
Adresse:
i:
o:
39
C = 27H
A = OOH
Ausgeführte Funktion
keine Funktion
-'.., . «. ,~ ..4.4 • _> ? t i i J
49
BDOS -Funktionen
Nummer: 40
Bezeichnung:
Adresse:
Write Random with Zero FillDirekter Schreibzugriff mit Initialisierung
OD9BH
I: C - 28HDE -> FCB mit Random Record Nummer
O: A Fehlercode- 0- 2- 3
kein FehlerDiskette vollder zuletzt angewählte Extend kannnicht geschlossen werdenein neuer Eintrag konnte nichtwerdendie gewählte Recordnummer ist größerals 65535
geöffnet
Ausgeführte Funktion:
Diese " Funktion entspricht der 'Write Random'-Funktion, mitder Ausnahme, daß neu belegte Blöcke initialisiert werden.Beim Erreichen eines neuen, bisher nicht belegten Blocks,wird der gesamte Block mit OOH gefüllt. Dadurch kann einProgramm bei einem späteren Lesezugriff, daß Ende des Filesgenau bestimmen.
50
BIOS-Funktionen
i BIOS-Funktionen
Alle BIOS-Funktionen werden über eine Sprungtabelle erreicht,die sich direkt an das BDOS anschliesst. Das BDOS benutzt dieeinzelnen Funktionen durch einen 'CALL1 zu der entsprechendenTabellenposition.
Im folgenden soll der Aufbau der Sprungtabelle und die Para-meterübergabe zu den BIOS-Funktionen beschrieben werden. Dadie Realisierung eines BIOS jedoch stark vom jeweiligen Com-putersystem abhängt, wird auf die Funktionen im einzelnennicht weiter eingegangen.
Das BIOS bekommt Funktionsparameter grundsätzlich im RegisterC bzw. bei 16-Bit Werten im Registerpaar BC übergeben undteilt dem BDOS das Funktionsresultat im Register A mit.
BIOS-Sprungtabelle
Die Sprungtabelle am Anfang des BIOS bzw. am Ende desmuß folgenden Aufbau haben:
BDOS
Adresse Sprungbefehl Funktion
BIOS+OOH
BIOS+03H
BIOS+06H
BIOS+09H
BIOS+OCH
BIOS+OFH
BIOS+1 2H
BIOS+1 5H
BIOS+1 8H
BIOS+1BH
BIOS+1 EH
BIOS+21H
BIOS+24H
JP
JP
JP
JP
JP
JP
JP
JP
JP
JP
JP
JP
JP
CBOOT
WBOOT
CONST
CON I N
CONOUT
LIST
PUNCH
READER
HOME
SELDSK
SETTRK
SETSEC
SETDMA
jKaltstart, System-; Initialisierung; Warmstart, CCP undJBDOS nachladen;Status der Consolen-Jeingabe testen
.,,, , jConsoleneingabe ,
; Con solenausgabe
; ' List ' -ausgäbe; ( Drucker ); ' Punch ' -Ausgabe
; 'Reader ' -Ausgabe
;Spur 0 anwählen
JDisk anwählen
JSpurnummer setzen
;Logische Sektornummer; setzen: DMA-Adresse fest-;legen
51
BIOS-Funktionen
BIOS+27H
BIOS+2AH
BIOS+2DH
BIOS+30H
JP READ
JP WRITE
JP LISTST
JP SECTRAN
jLogischen Sektor;lesen;Logischen Sektor;schreiben;Status der Drucker-;ausgabe testen;Sektornummer aus der;Verschränkungstabelle;holen
BIOS-Funktionen
Name: CBOOT, Cold BOOTKaltstart ausführen
I:
O: Sprung zum CCP oder Übergang in die Warmstart-Funktion
Funktion:
Der Kaltstart wird nur nach dem erstmaligen Laden des Be-triebsystems benötigt.Der Aufruf an den Kaltstart erfolgt meist von einem speziel-len Ladeprogramm, das nach dem Einschalten des Rechners, dasBIOS von der Systemdiskette geladen hat.Aufgabe des Kaltstart ist es, die einzelnen Systemkomponentenzu initialisieren und eine Meldung über den erfolgten System-start auf der Console auszugeben.Falls der CCP und das BDOS bereits im Speicher stehen, kannnach dem Kaltstart sofort der CCP aktiviert werden. In diesemFall müssen aber die beiden Sprungbefehle an den AdressenBOOT (nach BIOS+0003h) und BOOT+0005h (nach FBASE+OOOöh)eingesetzt sein. Normalerweise wird nach einem Kaltstart einWarmstart ausgeführt, der den CCP und das BDOS von der Disk-ette lädt und die Sprungbefehle einsetzt. Dann braucht nurdie zuerst anzuwählende Disk- und Usernummer in die Speicher-adresse BOOT+0004h eingetragen zu werden.
Name: WBOOT, Warm BOOTWarmstart ausführen
i:
O:
Funktion:
Sprung zum CCP
Ein Warmstart wird ausgeführt, wenn ein Programm durch einenSprung nach BOOT beendet wird oder das Zeichen CTRL-C von derConsole erkannt wurde.
52
BIOS-Funktionen
Der Warmstart muß die beiden Betriebssystem-Teile CCP undBDOS von der Diskette nachladen und die Sprungbefehle an denAdressen BOOT und BOOT+0005h neu setzen.Vor dem Wiedereintritt zum CCP, sollte das C-Register mit demWert der Speicherstelle BOOT+0004H geladen werden. Dadurchist sichergestellt, daß nach einem Warmstart der CCP wiederdas selbe Laufwerk und den selben Userbereich wie vorheranwählt.
Name: CONST, CONsole STatusConsolenstatus testen
l:
O:>r- f . \'
A = Consolenstatus- FFH, falls ein
ansteht- OOH, sonst
Zeichen von der Console
Funktion:
Der Consolenstatus zeigt an, ob ein Zeichen von der Consoleansteht, daß über die Consoleneingabe geholt werden sollte.Diese BIOS-Funktion wird vom BDOS bei jeder Zeichenausgabezur Erkennung der Steuerzeichen CTRL-S und CTRL-C aufgerufen.
Name: CONIN, CONsole INputConsolenzeichen holen
i:
05
Funktion:
A = Zeichen von der Console
Diese Routine holt ein Zeichen von der Console (Tastatur) undgibt es im A-Register zurück. Falls kein Zeichen von derConsole ansteht, muß auf ein Zeichen gewartet werden.
Name: CONOUT, CONsole OUTputZeichen zur Console ausgeben
C = Zeichen im ASCII-Code
o:
Funktion
Der im Register C befindlicheschirm) ausgegeben.
Wert wird zur Console (Bild-
53
BIOS-Funktionen
Name: LIST, LIST outputZeichen zum 'List '-Kanal (Drucker) ausgeben
I; C - Zeichen im ASCII-Code
o:
Funktion:
Wie Consolenausgabe, aber zum ' List ' -Kanal.
Name: PUNCH, PUNCH outputZeichen zum ' Punch ' -Kanal ausgeben
I: C - Zeichen im ASCII-Code
O:
Funktion:
Wie Consolenausgabe, aber zum ' Punch ' -Kanal
Name: READER, READER inputZeichen vom ' Reader ' -Kanal holen
i:
O; A = Zeichen vom ' Reader ' -Kanal
Funktion:
Wie Consoleneingabe , aber vom 'Reader ' -Kanal
Name: HOME, HOME diskSpur 0 anwählen
•»'. - T V .•>. ,« t^iü. ,if '. ,<—-••№ *••> .-nS-, -^ •'•••' - "rt t «r*.«-«-
i:
o:
Funktion:
Diese Funktion war bei älteren Laufwerken zur exaktenPositionierung des Schreib/Lesekopfes gedacht.Da das BDOS vor jedem Diskzugriff die Spurnummer über SETTRKanwählt, ist HOHE bei neueren Laufwerken überflüssig.
54
t
BIOS-Funktionen
Name: SELDSK, SELect DISKLaufwerk anwählen
T; . C Laufwerksnummer0 für Laufwerk A:
• • •
- 15 für Laufwerk P:E,0 - Login-Bit
i- - 0, falls das Laufwerk zum ersten Malangewählt wird
- 1 , falls das Laufwerk seit dem letztenWarmstart schonmal angewählt wurde
0: HL -> DPH des Laufwerks,r HL - 0, falls das Laufwerk nicht existiert
Funktion:
Das BIOS muß die im C-Register übergebene Laufwerksnummerüberprüfen und, falls ein Laufwerk mit dieser Nummer exis-tiert, in HL die Adresse des zugehörigen DPH zurückgeben,Im CP/n ist nicht garantiert, daß nach einem SELDSK-Aufrufauch tatsächlich auf dieses Laufwerk zugegriffen wird.Vielmehr hat der SELDSK-Aufruf nur eine 'Anmeldefunktion1,damit sich das BDOS auf das Laufwerk einstellen kann.Das BIOS muß die Laufwerksnummer aber intern speichern, dasich nachfolgende Diskzugriffe immer auf das zuletzt selek-tierte Laufwerk beziehen.
Name: SETTRK, SET TRacK« Spurnummer setzen... * % • •. • u , •' ' -t. -j- *• , ... . i- • • - - r
I: BC = Spurnummer
o:
Funktion:
Der nächste Diskzugriff bezieht sich auf die im RegisterpaarBC übergebene Spur. Die so gesetzte Spurnummer, errechnetsich immer aus der BDOS-internen (logischen) Spurnummer plusdem OFF-Wert im DPB. Wie auch beim SELDSK-Aufruf ist eintatsächlicher Diskzugriff nicht garantiert.
55
BIOS-Funktionen
Name: SETSEC, SET SECtorLogische Sektornummer setzen
I: BC - Logische Sektornummer
O:
Funktion:
Der nächste Diskzugriff bezieht sich auf den im RegisterpaarBC übergebenen Sektor. Die so gesetzte Sektornummer ist immerdas Ergebnis der SECTRAN-Funktion (s.u.). Auch hier ist eintatsächlicher Diskzugriff auf diesen Sektor nicht garantiert.
Name: SETDMA, SET DMA-addressDMA-Adresse festlegen
I: BC - DMA-Adresse
O:. ,-| ..T", ,< ,t.J'.' "r'-T,'"l "• V '-'- "„*">•,-*•;•• - . •-«!• ! . * » ,'-
Funktion:
Alle nachfolgenden Diskzugriffe müssen die DMA-Adresse alsQuell- (bei Schreibzugriffen) bzw. Zieladresse (bei Lesezu-griffen) benutzen.Die DMA-Adresse zeigt immer auf einen 128-Byte großen Buffer,weshalb Diskzugriffe immer in Recordgröße erfolgen.
Name: READ, READ sectorLogischen Sektor lesen
i:
O: A = Fehlercode= 0, kein Fehler
„Vl,.tfl.._,... ,,...„,„. = 1 / sonst , ..*,v,*..<,-.-«-
Funktion:
Die READ-Funktion liest einen (logischen) Sektor von derDiskette in den DMA-Buffer. Die Disknummer, Spurnummer undSektornummer sind jeweils durch die letzten SELDSK-, SETTRK-und SETSEC-Aufrufe festgelegt.Bei physikalischen Sektorlängen vom mehr als 128 Bytes, mußdas BIOS einen Sektorbuffer entsprechender Große selbst be-reitstellen und aus diesem Buffer, 128 Bytes zum zuletztdefinierten DMA-Buffer kopieren.Falls ein Lesefehler auftritt, sollte das BIOS den Diskzu-griff ein paar Mal wiederholen und, falls der Fehler bestehenbleibt, den Fehlercode 1 im A-Register zurückgeben.
56
BIOS-Funktionen
Name:
o:
WRITE, WRITE sectorLogischen Sektor schreiben
C - Record-Flag- 0, bei einem normalen Schreibzugriff- 1 , falls der logische Sektor ein
Directory-Record ist- 2, falls der logische Sektor der erste
Sektor eines neuen Blocks ist
A - Fehlercode- 0, kein Fehler- 1. sonst
Funktion:
Die WRITE-Funktion schreibt einen (logischen) Sektor vom DMA-Buffer auf die Diskette. Die Disknummer, Spurnummer und Sek-tornummer sind jeweils durch die letzten SELDSK-, SETTRK- undSETSEC-Aufrufe festgelegt.Bei physikalischen Sektorlängen von mehr als 128 Bytes, kanndas Record-Flag zur Realisierung eines 'Blocking'-Algorithmusverwendet werden. Bei einem normalen Schreibzugriff reichtes, den logischen Sektor nur in den BIOS-internen Sektorbuf-fer zu übernehmen. Dies hat den Vorteil, daß nachfolgendeSchreibzugriffe auf den selben physikalischen Sektor, keinenDiskettenzugriff verlangen. Erst wenn der neue logische Sek-tor in einem anderen physikalsichen Sektor liegt, muß derSektorbuffer auf die Diskette geschrieben werden.Directory-Schreibzugriffe sollten immer direkt auf dieDiskette geleitet werden.
Name:
i:
o:
LISTST, LIST output STatusStatus der Druckerausgabe testen
A = Druckerstatus= OOH, Drucker nicht bereit= FFH, Drucker frei
Funktion
LISTST wird vom BDOS nicht benötigt, sondern dient dem CP/MHilfsprogramm 'DESPOOL1 den Status der Druckerausgabe zubestimmen.
57
BIOS-Funktionen
Name: SECTRAN, SECtor TRANslationSektornummer aus der Sektor-Verschränkungs-Tabelle holen
I: BC - Logische SektornummerDE -> Sektor-Verschränkungs-Tabelle
O: HL - (Logische) Sektornummer aus der Tabelle
Das BDOS benutzt diese Funktion, um aus der im DPH angegebe-nen Sektor-Verschränkungs-Tabelle die Sektornummer zu entneh-men. Im allgemeinen genügt es, einfach die im Registerpaar BCübergebene Sektornummer ins Registerpaar HL zu kopieren.
58
-•• v
Hinweise
Hinweise zu den Source-Listings
Die auf den folgenden Seiten abgedruckten Source-Listings vonCCP und BDOS sind Ausgaben eines Assemblers. Beide Listingssind auf die Adresse OOOOH assembliert , da die Lage von CCPund BDOS im Speicher abhängig vom Computersystem ist.Die tatsächliche Adresse von BDOS+0006H kann jeweils über denInhalt der Speicherplätze 0006H und 0007H bestimmt werden.
Zeichen- und Begriffserklärung
Abkürzungen:
UPRO Abkürzung für ' UnterPROgramm 'I: Registerbelegung beim Start des UnterprogrammsO: ' Registerbelegung nach Ende des Unterprogramms# Abkürzung für 'Nummer1
-> Abkürzung für 'enthält Adresse von1 oder'ist Zeiger auf*
Assembler -Direktiven:
equ Label als Konstante defininierendefb Konstante einmal im Speicher ablegendefs Konstante mehrfach im Speicher ablegendefm Text im Speicher ablegen
Labe l -Definitionen:
Ülabel Label ist Datenlabel?label Label ist Programmlabel?§label Label ist Adresse eines Datum§label? Label ist Flag ('wahr1 oder 'falsch')label? Label für ein Unterprogramm, daß 'wahr' oder
'falsch1 zurückgibt
Hexadezimale Werte sind grundsätzlich zwei- oder vierstelligund mit 'h1 am Ende angegeben. Alle anderen Werte sind dezi-mal,
59
Hinweise
-44*1«.,* t»«** *» . t-
60
CCP-Listing
t•9 CCP Source Listing
; Dies sind Equates für die verschiedenen ASCII-Zeichen
000700080009OOOAOOOD001 0001 A0020
.,. , ,.„, . 00 3E
007F
= bellback
= tab- If
crctrlpeofspaceprompt
= del
equequequequequequequequequ " ' 'equ
07h08h09hOahOdh1 Oh1ah20h• |1 > '7fh
;Dies ist CTRL-P;Dies ist CTRL-Z;Leerzeichen;CCP Promptzeichen;Delete Code
; 'BOOT'-Adresse für dieses System
0000 ?boot ;qu OOOOh
r
; Adresse, an der die Nummer der aktuellen Disk; gespeichert ist:
0004 §disk equ ?boot + 0004h
; Einsprung ins BDOS:
,. 0005 = - ?bdos • - > •> equ ; ?boot + 0005h
; Adresse des vom CCP aufgebauten FCB
005C ?default_fcb equ ?boot + 005ch
; Adresse des Standard-Disk-Buffers:
0080 §buffer equ ?boot + 0080h
; Startadresse des Anwenderprogramm-Bereichs:; (Transient Program Area)
0100 ?tpa_start equ ?boot + 0100h
61
CCP-Listing
- <(" f.
; Hier sind die Nummern der verschiedenen vom (; benutzten BDOS-Funktionen definiert:J; Das 'b_' am Labelanfang, kennzeichnet es als; BDOS-Funktionsname:
0001
0002
OOOA
OOOB
OOOD
OOOE
OOOF
0010
0011
0012
0013
001 4
0015
0016
001 7
0018
001 9
001A
0020
0025
b_console_input
b_console_output
b read buffer
b_console status
b reset system
b_select_disk
b_open_file
b close file
b_search first
b_search next
b_delete_f ile
b read sequ
b_write_sequ
b_make_file
b rename file
b return disk
b_return_current . .
b set dma
b_set_get_user
b reset_disk
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ ,.
equ
equ
equ
1
2
1 0
11
13
14
1 5
16
17
18
19
20
21
22
23
24
.,- 25
26
32
37
62
CCP-Listing
; Startadresse des CCPtccp
; Dies ist der normale Einsprung zum CCP nach einem; Warmstart.; Falls jedoch ein AUTO-Befehl definiert ist, sollte nur; nach dem Kaltstart hierhin gesprungen werden.•/; I: C - Usernummer * 16 + Disknummer
0000 C3 035C JP start disk c
v.'; Einsprung zum CCP ohne Ausführung eines AUTO-Befehls•t; I: C - Usernummer * 16 + Disknummer»9
0003 C3 0358 JP start no command
; Dies ist der CCP-Befehlszeilen-Buffer.; Jede übernommene Befehlszeile wird hier zwischengespeichert; und ausgewertet.; Hier kann auch beim Einsprung in den CCP ein Befehl stehen.; Auf diese Weise lässt sich ein AUTO-Befehl realisieren, der; direkt nach dem Systemstart ausgeführt wird.
icmd buffer
0006 7F
0007 00
0008 20
defb 127
defb 0
defs 16,space
' ' ;Länge des Buffers
;Anzahl der eingege-;benen Zeichen im;Buffer
jKein AUTO-Befehl imjNormalfall
63
CCP-Listing
0018 43
003E 00
defm 'COPYRIGHT (C)'defm '1979, DIGITALdefm 'RESEARCH '
defs 74,0
;Copyrightvermerk der;Fa. Digital Research
;Rest des Buffers auf;füllen
?buffer address:
0088 0008 defw §cmd buffer+2 ;Adresse des nächsten;Zeichens während der^Auswertung des Buf-; fers
?first char:
008A 0000 defw 0 ;Adresse des ersten;Zeichens eines ein-;gegebenen Befehls.;Wird bei command_;error benutzt.
64
CCP-Listing
I°, CCP-interne Konsolenausgabe./; I: A - auszugebendes Zeichen•
; o: - ••tconout:t008C 5F LD E,A ;E - auszugebendes
;Zeichen008D OE 02 LD C,b_console_output;C - BDOS-Funktions
;nummer008F C3 0005 JP ?bdos ;BDOS-Aufruf
-> y.-» 1-4; Console Ausgabe , - • •; mit Rettung des Registerpaares BC
I: A - auszugebendes ZeichenrO: -
tconout_bc:•
0092 C5 PUSH BC ;BC auf Stack0093 CD 008C CALL conout ;Zeichen Ausgabe0096 C1 POP BC ;BC von Stack0097 C9 RET
; Ausgabe von Carriage Return (er) und Line Feed (If); zur Beendigung einer Ausgabezeile.•/ .•'*•. ,print__crlf:•f0098 3E ÖD LD A,er ;A = cr-Code009A CD 0092 CALL conout_bc ;Zeichen ausgeben009D 3E OA LD A,lf ;A = lf-Code009F C3 0092 JP conout_bc ;Zeichen ausgeben•/•/; Ausgabe eines Leerzeichens.tprint_space:•/OOA2 3E 20 LD A,space ;A = LeerzeichenOOA4 C3 0092 JP conout_bc ;Zeichen ausgeben
65
CCP-Listing
; Ausgabe eines Textes.•; I: BC -> Text, abgeschlossen mit OOH
print_text:•/OOA7 C5 PUSH BCOOA8 CD 0098 CALL print_crlf
OOAB E1
print_loop:
POP HL
A,(HL)AZHLHLconoutHLprint_loop
; BDOS in den Ausgangszustand bringen
OOACOOADOOAEOOAFOOBOOOB1OOB4OOB5
•
•/
7EB7C823E5CD 008CE1C3 OOAC
LDORRETINCPUSHCALLPOPJP
reset_system:•
OOB8 OE ÖD LD
OOBA C3 0005 JP
C,b_reset_system
?bdos
;Textzeiger retten;Neue Ausgabezeile;beginnenjTextzeiger zurück;nach HL
;A - nächstes Zeichen;ist es OOH ?;J: fertig;N: Zeiger +1; Zeiger retten; Zeichen ausgeben;Zeiger zurück;nächstes Zeichen;holen
;C = BDOS-Funktions-jnummer;BDOS-Aufruf
; Neue Disk anwählen•t; i: A = Disknummer (OOH = A: .. OFH = P:)
select_disk:•
OOBD 5FOOBE OE OE
LDLD
OOCO C3 0005 JP
v v • f- *•- ».
E,AC,b_select_disk
?bdos
;E = Disknummer;C = BDOS-FunktionsJnummer;BDOS-Aufruf
66
CCP-Listing
I
; CCP-interner BDOS-Aufruf für BDOS-Funktionen, die; einen Fehlercode zurückgeben (File-Funktionen).•/; I: C = BDOS-Funktionsnummer; DE - BDOS-Parameter (FCB-Adresse)
; O: A = 0 bei fehlerhaftem BDOS-Aufruf: < > 0 sonst
bdoscall :
OOC3OOC6OOC9OOCA
CD323CC9
000507EE
CALLLDINCRET
?bdos( return_code ) , AA
;BDOS-Aufruf;Fehlercode speichern;A - Fehlercode+1
; File eröffnen•; I: DE -> FCB•i•r O: A - 0 bei Fehler (File nicht gefunden)•topen_f ile:
OOCB OE OF LD C,b_open_file ;C - BDOS-Funktions;nummerJBDOS-AufrufOOCD C3 OOC3 JP bdos call
; Internen FCB eröffnen
; O: A = 0 bei Fehler (File nicht gefunden)•/open_fcb:
OODO AF XOR
OOD1 ?2 07ED LDOOD4 :1 07CD LD
OOD7 C3 OOCB JP
A JA = 0; Interne RecordnummerJauf 0 setzen
(internal_record__#), ADE,internal_fcb ;DE = Zeiger auf
; internen FCBopen_file jFile eröffnen
67
CCP-Listing
t; File seh 1 lessen*
; I: DE -> FCB•i; O: A = 0 bei Fehler•fclose_f ile :*
OODA OE 1 0 LD C , b_close_f ile ;C - BDOS-Funktions-; nummer
OODC C3 OOC3 JP bdos_call ;BDOS-Aufruf•/•r; Ersten Directory-Eintrag eines Files suchen•
; I: DE -> FCB•r•r Oi A - 0 falls kein Eintrag gefunden wurde•/search_f irst :•rOODF OE 1 1 LD C/b_search_first ;C - BDOS-Funktions-
; nummerOOE1 C3 OOC3 JP bdos__call ;BDOS-Aufruf
; Nächsten Directory-Eintrag eines Files suchen•/; i: -•/; 0: A = 0 falls kein weiterer Eintrag gefunden wurde•/search_next:iOOE4 OE 1 2 LD C , b_search_next ;C = BDOS-Funktions-
; nummerOOE6 C3 OOC3 JP bdos_call ;BDOS-Aufruf
; Ersten Directory-Eintrag des internen FCB suchen
; i: -•.r; O: A = 0 falls kein passender Eintrag gefunden wurde•rsearch fcb:
r
OOE9 11 07CD LD DE,internal_fcb ;DE -> interner FCBOOEC C3 OODF JP search_first ;Ersten Eintrag
;suchen
68
CCP-Listing
; File löschen
1: DE -> FCß
; O: A BDOS-Fehlercode
delete file:
OOEF OE 13 LD
OOF1 C3 0005 JP
C,b_delete file
?bdos
;C - BDOS-Funktions-;nummer;BDOS-Aufruf
Gemeinsamer BDOS-Aufruf für Schreib- und Leseoperationendes CCP.
I: C BDOS-FunktionsnummerDE -> FCB
; O: A - BDOS-Fehlercode; Flags gesetzt
bdos_diskio:•
OOF4 CD 0005 CALLOOF7 B7 OROOF8 C9 RET
?bdosA
;BDOS-Aufruf;Flags setzen
; Nächsten Record lesen•
; l: DE -> FCB•
'; O: A = BDOS-Fehlercoderead_sequ:
OOF9 OE 1 4 LD
OOFB C3 OOF4 JP
C, b_read_sequ
bdos diskio
;C = BDOS-Funktions-jnummerJBDOS-Aufruf
; Nächsten Record des internen FCB lesen
read_fcb:»
OOFE 11 07CD LD0101 C3 OOF9 JP
DE,internal_fcb ;DE -> interner FCBread_sequ ;Record lesen
69
CCP-Listing
; Nächsten Record schreiben»
; I: DE -> FCB
; O: A BDOS-Fehlercode
write sequ:
0104 OE 15 LD
0106 C3 OOF4 JP
C,b_write_sequ
bdos diskio
;C - BDOS-Funktions-;nummer;BDOS-Aufruf
; Neues File anlegen
I: DE -> FCB
; O: A - BDOS-Fehlercode
make file:
0109 OE 16 LD-«*,.
01 OB C3 OOC3 JP
C,b__make_f ile
bdos call
;C - BDOS-Funktions;nummer;BDOS-Aufruf
; File umbenennen*
; i: DE -> FCB*I• O: A = BDOS-Fehlercode•/rename file:
01OE OE 17 LD
0110 C3 0005 JP
C,b rename file
?bdos
;C = BDOS-Funktions-;nummer;BDOS-Aufruf
70
t
•t Aktuelle Usernummer holen
CCP-Listing
; 0: A - Usernummer
get_user:•
0113 1E FF LD E,OFFH ;E - BDOS-Parameter;für 'Usernummer;holen'
; Usernummer setzen•i; I: E - neue Usernummer
; o: -
setuser :
0115 OE 20 LD
0117 C3 0005 JP
C, b_set_get_user
?bdos
;C - BDOS-Funktions-;nummer;BDOS-Aufruf
; Aktuelle Disk- und Usernummer zusammenfassen; und in §disk setzen.*/set drv usr:
011A011D01 1E01 1F012001 21
CD8787878721
01 1 3
07EF
CALLADDADDADDADDLD
0124 B6 OR0125 32 0004 LD0128 C9 RET
get_userA,A , ,A,AA,AA, AHL,ccp_disk
(HL)(§disk),A
;Usernummer holen;*2;*4;*8;A = Usernummer * 16;HL -> aktuelle Disk-jnummer;Disknummer einmaskie-;ren und speichern
71
CCP-Listing
; Aktuelle Disknummer in §disk speichern
set_disk:*
0129 3A 07EF LD
012C 32 0004 LD012F C9 RET
A,(ccp_disk)
(§disk),A
;A - aktueJle Disk-;nummer;nach §disk speichern
; Zeichen in Großbuchstaben wandeln•/; l: A - ASCII-Zeichen in Groß- oder Kleinschrift•i; O: A - ASCII-Zeichen in Großschrift
make_upper:•
0130 FE 61
0132 D8.1 A »r A /"' •> ", ' J- '
0133 FE 7B
0135 DO
0136 E6 5F
0138 C9
CP
RET
CP
RET
AND
RET
'a1
C- r r* ' .>
'ä'
NC
05FH
;Ist das Zeichen;kleiner als 'a' ?;J: Zeichen ist kein;Kleinbuchstabe;N: Ist das Zeichenjgrößer als 'ä' ?;J: Zeichen ist kein;Kleinbuchstabe;N: Zeichen in Groß-;buchstaben wandeln
72
CCP-Listing
; Befehlszeile holen»/; Je nach Wert des 'submit_flag' wird die nächste Befehls-; zeile von der Console (Tastatur) oder aus dem Submit-; file $$$.SUB geholt.
get_command_line:
0139 3A 07AB LD01 3C B7
01 4901 4C
01560159015C01 5F
OR01 3D CA 0196 JP
0140 3A 07EF LD
,0143 B7 t-, , OR
A,{submit_flag)AZ,no_submit
A,(ccp_disk)
A
0144 3E 00 LD A,00146 C4 OOBD CALL NZ,select disk
1 1 07ACCD OOCB
LDCALL
014F CA 0196 JP
0152 3A 07BB LD
0155 3D DEC
32 07CC11 07ACCD OOF9C2 0196
LDLDCALLJP
DE ,open
fcb
;A - Submit Flag;Sut>mit aktiv ?;N: Zeile von Consolejholen;J: A - aktuelle Disk;nummer;Ist A: die aktuelle;Disk ? (Disknummer;- 0 ?);A - 0;N: Disk A: a n -;wählen
.SUBfile
Z,no_submit
;DE -> FCB für;FCB öffnen,;vorhanden ?;N: Zeile von Consolejholen;J: Letzten Record;von $$$.SUB lesen:
A,(submit_rec_count);A = Anzahl der;Records im $$$.SU3-
*> ,1*..-•- , '-.* -«/.-/, .-•*,! jFile;= Nummer des letztenJRecords in $$$.SUB+1
A ;A = A-1;Nummer des zu lesen-;den Records in den;submit_fcb setzen
(current_submit_rec),ADE,submit_fcb ;DE -> submit_fcbread_sequ ;Record lesenNZ/no_submit ;Fehler ?
;J: Zeile von Console;holen
73
CCP-List inq
U >> .- H TvV
0162 11 0007 LD DE,§cmd_buffer+10165 21 0080 LD HLf§buffer0168 06 80 LD B,128
016A CD 0442 CALL move b bytes
016D 21 07EA
0170 36 00
D
LD
HL,submit_fcb_na
(HL),0
0172 23
0173 35
INC
DEC
HL
( HL )
0174 11 07AC LD DE,submit_fcb0177 CD OODA CALL ciose_file017A CA 0196 JP Z,no submit
017D 3A 07EF LD0180 B7 OR
A,(ccp_disk)A
0181 C4 OOBD CALL NZ,select_disk
0184 21 0008 LD HL,§cmd_buffer+2
0187 CD OOAC CALL print__loop018A CD 01C2 CALL check_console018D CA 01A7 JP Z,set command
0190 CD 01DD CALL delete_submit0193 C30382 JP ccp_prompt
;N: Zeile vom disk-;buffer in den Be-;fehlsbuffer über-;nehmen;DE -> Bufferstart;HL -> Diskbuffer;B - Anzahl der zu; übertragenden Bytes;B Bytes von HL nach;DE übertragen
HL -> 'Not altered'-Flag im $$$.SUB-FCBauf 0 setzen.Damit ist das Fileals 'verändert' mark-iert und der folgende'Close File'-Aufrufschreibt die neueFilelänge zurück indie Directory,(siehe auch '_close_file' im BDOS)HL -> Anzahl derRecords im $$$.SUB-FileRecordnummer -1, dagerade ein Recordgelesen wurde
;DE -> submit_fcb;$$$.SUB schliessen;Fehler ?;J: Zeile von Console;holen
;A = CCP Disknummer;war die CCP-Disk;gleich A: ?;N: Disk neu anwählen
;HL -> Submit Befehls-;zeileJSubmitbefehl ausgeben;Taste gedrückt ?;N: Submitbefehl aus-;führen
;J: Submit abbrechen;$$$.SUB löschen; Zurück zum CCP-Prompt
74
Befehlszeile von der Console holen
no submit:
CCP-Listing
019601 99
01 9E01A1
"01A4
CD 01DDCD 011 A
019C OE OA
11 0006CD 0005CD 0129
CALLCALL
LD
delete_submitset drv usr
C,b read buffer
LD DE,§cmd_bufferCALL ?bdosCALL set disk
.SUB loschenAktuelle Disk- undUsernummer zusammen-fassen und für eineneventuellen Warmstartspeichern (siehe auchstart_disk_c)C - BDOS-Funktions-nummer für Eingabe-zeile holenDE - BufferadresseBDOS-AufrufDisknummer speichern
; Befehlszeile im Buffer zur Auswertung vorbereiten.; Alle Zeichen in Großbuchstaben umwandeln und Zeilenende; mit OOH markieren.•tset command:
01A7 21 0007 LD
01AA 46
convert_loop:r01 AB01 AC01 AD01 AE01B101B2
01B601B7
2378B7CA7ECD
01B5 77
01BA
0130
05C3 01 AB
LD
INCLDORJPLDCALL
LD
DECJP
HL,§cmd_buffer+1
B,(HL)
HLA,BAZ,reset_bufferA,(HL)make_upper
(HL),A
Bconvert_loop
;HL -> Anzahl der ein-^gelesenen Zeichen;B = Zeichenzähler
Zeiger +1A = ZählerZähler = 0 ?J: FertigZeichen holenIn GroßbuchstabenumwandelnZeichen zurück-schreibenZähler -1Nächstes Zeichenholen
75
CCP-Listing
; Zeilenende mit OOH markieren; Adresse des nächsten Zeichens auf Bufferanfang setzen
reset buffer:
01BA 77 LD
01BB 21 0008 LD
01 BE 22 0088 LD01 C1 C9 RET
(HL),A ;Zeilenende markieren;(A ist noch OOH vom;Zählertest bei 01AD)
HL,§cmd_buffer + 2 ;HL -> Bufferanfang^Adresse des nächstenjauszuwertenden Zei-jchens auf Bufferan-;fang setzen
(?buffer address),HL
; Console auf anstehendes Zeichen überprüfen und; Zeichen holent• T • —r •*- •
t
; O: A - 0, falls kein Zeichen anstand; - Zeichencode sonst•rcheck console:
01C2 OE OB
01C401C701C8
LD C,b_console_status;C = BDOS-Funktions-jnummer
CD 0005 CALL ?bdos ;BDOS-AufrufB7C8
01C9 OE 01
01CB CD 000501CE B701CF C9
ORRET
LD
CALLORRET
A ; Zeichen vorhanden ?Z ;N: fertig
;j; Zeichen holenC,b_console__input ;C = BDOS Funktions-
jnummer?bdos ;BDOS-AufrufA ;Flags setzen
* . ,.r "~• Aktuelle BDOS-Disknummer holen
r • _-*- •
; O: A = BDOS Disknummer
get_disk__code :
01DO OE 18 LD
01D2 C3 0005 JP
C,b_return_disk
?bdos
;C = BDOS Funktions-;nummer;BDOS Aufruf
76
CCP-Listing
; DMA-Adresse auf §buffer setzen
set default dma:
01D5 11 0080 LD DE,§buffer
; DMA-Adress setzen•/; I: DE - neue DMA-Adresse•r• O* -t v-/ •
set dma
01D8 OE 1A LD
01DA C3 0005 JP
C,b set dma
?bdos
;DE -> §buffer
;C - BDOS-Funktions-;nummer;BDOS-Aufruf
; Submit-File
delete submit
.SUB löschen
01DD01EO01E101E2
01E501E601E901 EC01EF01F2
21 07AB7EB7C8
01E3 36 00
AFCD OOBD11 07ACCD OOEF3A 07EFC3 OOBD
LDLDORRET
LD
XORCALLLDCALLLDJP
HL,submit_flagA,(HL)AZ
(HL),0
select_diskDE , submit_f cbdelete_f ileA, ( ccp_disk )select disk
;HL -> submit_flag;A - submit_flag;submit aktiv ?;N: dann braucht auch;nichts gelöscht zujwerden
'fJl submit_flag auf;inaktiv setzen;A = 0;Disk A: anwählen;DE -> submit_fcb;$$$.SUB löschen;Ä = CCP-Disknummer;CCP-Disk wieder an-Jwählen
77
CCP-Listing
Seriennummern von CCP und BDOS vergleichen
compare_serial:
01F5 11 0328 LD
01F8 21 0800 LD
01FB 06 06
compare _loop:
01FD01FE
1ABE
0208 C9
LD
LDCP
01 FF C2 03CF JP
0202020302040205
132305C2 01FD
INCINCDECJP
RET
DE,serial_number
HL,bdos
B,6
A,(DE)(HL)
NZ,wrong_serial
DEHLBNZ,compare_loop
;DE -> CCP Serien-;nummer;HL -> BDOS Serien-;nummer;6 Bytes vergleichen
;A = Byte aus CCP;gleich dem Byte aus;dem BDOS ?;N: falsche Serien-Dummer;CCP-Zeiger +1;BDOS-Zeiger + 1;Zähler -1^Nächstes Byte ver-gleichen
; Fehler in der Befehlszeile erkannt.; Ab dem ?first_char wird das nächste Wort oder der Rest; der Zeile, gefolgt von einem Fragezeichen ausgegeben./command error:
0209 CD 0098 CALL print_crlf
020C 2A 008A LD HL,(?first_char)
print_next_char:•
020F 7E LD0210 FE 20 CP
0212 CA 0222 JP0215 B7 OR
;Neue Ausgabezeile;beginnen;HL -> FehlerhafteBefehlszeile
0216021 9021A021D021E021F
CAE5CDE123C3
0222
008C
020F
JPPUSHCALLPOPINCJP
A,(HL) jZeichen holenspace '' -•-''•-•'"•' ;Leerzeichen ?
;J: Wortende erreicht,;Fragezeichen ausgeben
Z,print_question_markA ;OOH gefunden ?
;J: Zeilenende;erreicht, Frage-;zeichen ausgeben
Z,print_question_markHL ;N: Zeiger rettenconout ;Zeichen ausgebenHL ;Zeiger zurückHL ;Zeiger +1print__next_char ;nächstes Zeichen
78
CCP-Listing
im Anschluß an den fehlerhaften Befehl
einem Submit-File kam,
Fragezeichenausgeben.Falls der fehlerhafte Befehl auswird der SUBMIT-Lauf abgebrochen
print_question_mark:
022202240227022 A022D
3ECDCDCDC3
3F008C009801DD0382
LDCALLCALLCALLJP
A ' *? 't\ tconoutprint_crlfdelete_submitccp_prompt
;A - Fragezeichen;Zeichen ausgeben;Zeile beenden;$$$.SUB abbrechen; Zurück zum CCP-Prompt
Nächstes Zeichen aus, und überprüfen•i, I: DE -> zu holendes
dem Befehlsbuffer holen
Zeichen
O: A - ZeichenZ-Flag gesetzt, falls ein Trennungszeichen gefundenwurde. Trennungszeichen sind: - _ . : ; < >
get__check_char:
023002310232
1AB7C8
0233 FE 20
LD A,(DE)OR ARET Z
CP space
02350238
0239023B023C023E023F024102420244024502470248024A024B024D024E
DAC8
FEC8FEC8FEC8FEC8FEC8FEC8FEC8C9
0209
3D
5F
2E
3A
3B
3C
3E
JPRET
CPRETCPRETCPRETCPRETCPRETCPRETCPRETRET
C,cZ
i _ i
Z1 1
z"1 1•
z1 . 1•
z• * •t
z1 < 'z1 > 'z
C,command error
Zeichen holenZeichen - OOH ?J: ZeilenendeerreichtIst das Zeichen einControl-Code, alsokleiner als space ?J: Fehler • •ok, falls das Zeichengleich space ist.Zeichen gleich '=' ?J: okZeichen gleich '_' ?J: okZeichen gleich '.' ?J: okZeichen gleich ':' ?JI okZeichen gleich ';' ?JI okZeichen gleich '<' ?J: okZeichen gleich '>' ?J: okN: Das Zeichen istkein Trennungszeichen
79
CCP-Listing
Nächstes Zeichen ungleich Leerzeichen holen
I: DE -> Befehlszeile
O: A - 0 falls kein Zeichen rrehr gefunden wurde- Zeichen sonst
get_next_char:
024F02500251
1AB7C8
0252 FE 20
025402550256
CO1 3C3 024F
LDORRET
CP
RETINCJP
A zu HL addieren
I: A , HL
O: HL - HL -i- A
add hi a:
A,(DE)AZ
space
NZDEget next char
;A - nächstes Zeichen;Zeichen - OOH ?;J: Zeilenende;erreichtjLeerzeichen ge-;funden ?;N: Fertig;J: Zeiger +1jNächstes Zeichen;testen
0259025A025B
025C025D
856FDO
24C9
ADDLDRET
INCRET
A, LL, ANC
H
;Erst die LSBs ad-; addieren;Fertig, falls kein;ÜberlaufJSonst Überlauf in H;auffangen
80
CCP-Listing
; Zeichen ab ?buffer_address als Filenamen interpretieren; und in den internen FCB übernehmen.•/; I: ?buffer_address -> Filenamei; O: A - Anzahl der '?', die der Filenamen enthält; - 0, falls der Filename eindeutig ist
setup_fcb:
025E 3E 00 LD A,0
Zeichen ab ?buffer_address als Filenamen interpretierenund in den internen FCB ab Positon A übernehmen.Dieser Einsprang wird vom 'REN1-Befehl benutzt, um den <•*•internen FCB für die BDOS-Funktionszubereiten
'Rename File' vor-
setup_fcb_offset:
026002630266026702680269
21 07CDCD 0259E5E5AF32 07FO
LDCALLPUSHPUSHXORLD
HL,internal_fcbadd_hl_aHLHLA(file disk no),A
026C 2A 0088 LD
026F0270
02730274
EBCD
EB22
024F
008A
EXCALL
EXLD
DE,HLget_next
DE,HL( ?f irst
char
char )
0277 EB EX DE,HL0278 E1 POP HL0279 1A LD A,(DE)027A B7 OR A027B CA 0289 JP Z,no_new_disk
;HL -> interner FCB;A aufaddieren;FCB Zeiger zweimal;retten;A - 0;Aktuelle Disk als;Disk des Files an-;nehmen
HL,(?buffer_address)JHL -> Buffer
JNächstes Zeichen un-;gleich 'space1 holen
,HL ;Adresse dieses Zei-;chens für die Fehler-;routine merken;DE -> Buffer;HL -> FCB;Zeichen holen; Zeilenende erreicht ?;J: keine Diskbezeich-Jnung gefunden
81
CCP-Listing
027E DE 400280 470281 130282 1A
0283 FE 3A0285 CA 0290
SBCL DINCLD
CPJP
A, '§'B,ADEA , ( DE )
' . i*
Z .set
0288•t
1B DEC DE
N: Zeichen als Disk-bezeichnung auffassenDiskcode berechnenB - DiskcodeBufferzeiger +1nächstes ZeichenholenIst es ein ' : ' ?J: Das Zeichen wareine DiskbezeichnungN: Zeiger -1
; Keine Diskbezeichnung gefunden.; Als Disk für den internen FCB wird die aktuelle Disk; genommen.
no_new_disk:
0289 3A 07EF LD
028C 77 LD
028D C3 0296 JP
A,(ccp_disk)
(HL),A
setup_filename
;A - aktuelle Disk-;nummer;A als Disknummer in;den FCB übernehmen;Filenamen übernehmen
; Diskbezeichnung gefunden.
set_new_disk:
0290 78 LD0291 32 07FO LD0294 70 LD
0295 13 INC
A, B( f ile_disk_no(HL), B
DE
;A = Disknummer;Nummer merken;und in FCB über-;nehmenJBufferzeiger +1
82
CCP-Listing
; Filenamen in den FCB übernehmen.; Das Zeichen '*' wird als "Joker1 erkannt und die rest-; liehen Zeichen des Filenamens mit '?' aufgefüllt.
setup_filename:•
0296 06 08 LD B,8 ;Der Filenamen hatjmaximal 8 Zeichen
setup_filename_loop:
CD 0230 CALL get_check_char0298
029B CA 02B9 JP
029E029F02A102A4
23FEC236
2A02A93F
INCCPJPLD
jZeichen aus Buffer;holenjZeilenende erreicht ?
Z,fill_fcb_space ;J: restliche Zeichen-, _ ., . . . . ;im FCB mit Leerzei-
;chen auffüllenHL ;N: FCB-Zeiger +1'*' ;'Joker1 gefunden ?NZ,set_char_to_fcb;N: Zeichen übernehmen(HL),1?1 ;J: '?' einsetzen und
;Bufferzeiger NICHTjerhöhen
next_filename_char;Das nächste Zeichen;wird wieder l * 1 sein.;Dadurch werden diejrestlichen Zeichen;des Filenamens im FCBJmit '71 belegt
Zeichen in den FCB übernehmen und Bufferzeiger erhöhen
02A6 C3 02AB JP
set_char_to_fcb:i02A9
02AA
77
1 3
LD
INC
(HL) , A
DE
;Zeichen in FCB über-;nehmen;Bufferzeiger +1
Nächstes Zeichen vom Buffer in den FCB übernehmen, fallsnoch nicht 8 Zeichen erreicht sind.
next filename char:
02AB 05 DEC B
02AC C2 0298 JP
;Zähler -1;Zähler = 0 ?;N: nächstes Zeichen;übernehmen
NZ,setup_filename_loop
83
CCP-Listing
; Ende des Filenamens und damit den Anfang des Filetyps im; Buffer suchen.'rsearch_filetype:•r02AF CD 0230 CALL get_check_char ;Nä'chstes Zeichen aus
;dem Buffer holen.;Ist es ein Trennungs-;zeichen ?
02B2 CA 02CO JP Z,setup_filetype ;J: Ende des File-;namens erreicht
DE ;N: Bufferzeiger +1search_filetype ;und weitersuchen
02B5 13 INC02B6 C3 02AF JP
; Restliche Zeichen des Filenamens im FCB mit Leerzeichen; auffüllen.
02B902BA02BC02BD
_f cb_space :
23 INC36 20 LD05 DECC2 02B9 JP
HL ;FCB-Zeiger +1(HL),space ^.^ ;Leerzeichen einsetzenB ' ;Zähler -1NZ , f ill_f cb_space jWeiter, bis Zahler -0
; Filetyp in internen FCB übernehmen
; I: A = Trennungszeichen nach dem Filenamenrsetup_filetype:
02CO 06 03 LD
02C2 FE 2E CP
02C4 C2 02E9 JP
B,3 ;Der Filetyp hatJmaximal 3 Zeichen
'.' Jlst das Trennungs-Jzeichen ein Punkt ?
NZ,fill_typ_space ;N: Es folgt keinjFiletyp;Entsprechende Stellen;im FCB mit Leerzei-;chen auffüllen
84
CCP-Listing
02C7 13 INC DE ;J: Filetyp folgt,;Bufferzeiger +1
setup_filetype_loop:•/02C8 CD 0230 CALL get_check__char
02CB CA 02E9 JP
02D6 C3 02DB JP
Z,fill_typ_space
02CE02CF02D102D4
23FEC236
2A02D93F
INCCPJPLD
HL• * «
NZ,(HL
^Nächstes Zeichen aus;dem Buffer holen;Trennungszeichen ge-funden ?;J: Restliche Zeichen;mit Leerzeichen auf-;füllen;FCB-Zeiger + 1;'Joker1 gefunden ?
NZ , set_char_to_typ;N: Zeichen übernehmen;J: '?' einsetzen und;Bufferzeiger NICHT;erhöhen
next_filetype_char
; Zeichen in den FCB übernehmen und Bufferzeiger erhöhen
set_char_to_typ:
02D9 77 LD
02DA 13 INCtnext_filetype_char
02DB 05 DEC
_'». »-«U.«V;
02DC C2 02C8 JP
( HL ) , A
DE
;Zeichen in den FCBjeinsetzen;Bufferzeiger +1
B ;zähler -1;Zähler = 0 ?;N: nächstes Zeichen^übernehmen
NZ, setup_filetype_loop
; Ende des Filetyps suchen.*isearch_end_of_filetype:•02DF CD 0230 CALL get_check_char
02E2 CA 02FO JP02E5 13 INC02E6 C3 02DF JP
Z,clear_restDE
;Zeichen aus BufferJholen. Trennungs-;zeichen gefunden ?JJ: Fertig;N: Bufferzeiger +1
search_end_of_filetype
85
CCP-Listing
; Restliche Zeichen des Filetyps im FCB mit Leerzeichen; auffüllen.
f i l l_typ__space:•02E9 23 INC02EA 36 20 LD02EC 05 DEC02ED C2 02E9 JP
HL ;FCB-Zeiger +1(HL),space ^Leerzeichen einsetzen3 ;Zähler -1NZ,fill_typ_space ;Weiter, bis Zähler =0
; Die nächsten 3 Bytes im FCB auf OOH setzen
clear rest:
02FO 06 03 LD B,3 ;3 Bytes
clear_rest_loop:•
02F2 23 INC02F3 36 00 LD02F5 05 DEC02F6 C2 02F2 JP02F9 EB EX
02FA 22 0088 LD02FD E1 POP
HL ;Zeiger +1(HL),0 ;Byte auf OOH setzenB jZähler -1NZ,clear_rest_loop;Weiter, bis Zähler -0DE,HL ;HL - Bufferzeiger
;Aktuellen Bufferzei-;ger für nächsten;Aufruf abspeichern
{?buffer_address),HLHL ;FCB-Startzeiger
; zurück
; Aufgebauten FCB nach '?' absuchen
02FE 01 OOOB LD
check_wildcard :•
0301 230302 7E0303 FE 3F0305 C2 0309 JP0308 04
no_wildcard :•
0309 ÖD DEC030A C2 0301 JP
030D 78 LD
030E B7 OR030F C9 RET
INCLDCPJPINC
HLA , ( HL )i ? i
NZ,no wildcardB
*r'•
/•
r•
BC,11 ; B = 0 , C = 1 1
;FCB-Zeiger +1;Zeichen holen;ist es '?' ?;N: weiter
: ' ?' gefunden
C ;zähler -1NZ,check_wildcard ;Nachstes Zeichen
;überprüfenA,B ;A = Anzahl der ge-
;fundenen '?'A ;Flags setzen
86
CCP-Listing
Tabelle der vom CCP erkannten Befehle
cmd table:
031003140318031C03200324
444554535255
defmdefmdefmdefmdefmdefm
'DIR ''ERA ''TYPE''SAVE'' REN ''USER'
; CCP-Seriennummer
serial number:
0328 00 defs 6,0
; Eingegebenen Filenamen (Befehl) in der cmd_table suchen?; I: Befehl, über 'setup_fcb' im internal_fcb eingetragen
; O: A -t•t•
•t»9•t•t
Befehls in der cmd tablerelative Position des- 0 entspricht 'DIR1
- 1 entspricht 'ERA'- 2 entspricht 'TYPE1
= 3 entspricht 'SAVE'= 4 entspricht 'REN1
= 5 entspricht 'USER1
= 6 Befehl nicht erkannt (Programmname ?i)
search_ccp_cmd:•
032E 21 0310 LD HL,cmd_table0331 OE 00 LD C,0
;HL -> Befehlstabelle;C ist Befehlszähler
; Nächsten Befehl vergleichen9
rcompare_next__cmd:
033303340336
79FE 06DO
LDCPRET
A,C6NC
;lst der Befehlszähler;gleich 6 ?JJ: Keinen der sechs;Befehle erkannt.
87
CCP-Listing
0337 11 07CE LD033A 06 04 LD
compare_next__char:
033C 1A
033D
033E
034103420343
BE
C2 034F
132305
LD
CP
JP
INCINCDEC
0344 C2 033C JP
0347 1A LD
0348 FE 20 CP
034A C2 0354 JP034D 79 LD
;J: DE ->;(Befehl)
Filename
DE , intern.B,4
A,(DE)
il_f ilename;4 Zeichen werden;maxjmal verglichen
;Stimmt das; Zeichen au:
NZ,ine
DEHLB
nächstedem File-
;namen mit dem nächs-(HL) ;ten Zeichen der Be-
;fehlstabelle überein?to_next_cmd;N: Befehlstabellen-
;zeiger auf nächsten;Befehl erhöhen;J: Befehlszeiger +1;Tabellenzeiger +1; Zeichenzähler -1;Alle 4 Zeichen ver-;glichen ?;N: Nächstes Zeichen;prüfen
NZ,compare_next_char;J: Die ersten 4 Zei-;chen des Filenamens;wurden erkannt.;Ist aber der einge-;gebene Befehl damit;abgeschlossen ?
A,(DE) ;Nächstes Zeichen des;Filenamens holen
space ;Folgt ein Leer-;zeichen ?;N: Befehl nicht voll-; ständig erkannt
NZ,ineA,C
cmd counter
034E C9
;J: A = relative Num-;mer des erkannten;Befehls
RET
; Befehlstabellenzeiger auf nächsten Befehl erhöhen•rinc to next cmd:
034F 23 INC0350 05 DEC0351 C2 034F JP
HL ;Zeiger +1B ;Zeichenzähler -1NZ,inc_to_next_cmd;Weiter, bis Zeichen-
;zähler = 0
88
CCP-Listing
; Befehlszähler erhöhen und nächsten Befehl vergleichen•/ine _cmd_counter:
0354 OC INC C Befehlszähler +10355 C3 0333 JP compare_next_cmd ;Nächsten Befehl ver-
gleichen
; CCP-Start ohne Ausführung eines Auto-Befehls•r•f I: C - Zusammengef asste User- und Disknummer für die; weitere Bearbeitung•/start__nc_command:
0358 AF XOR A ;A - 00359 32 0007 LD (§cmd_buffer+1),A ;Anzahl der im Buffer
Befindlichen Zeichen;auf Null setzen
; CCP-Start mit Ausführung eines Auto-Befehlsi•r I: C - Zusammengef asste User- und Disknummer für die; weitere Bearbeitung
start_disk_c:•
035C 31 07AB LD SP,stack_area035F C5 PUSH BC
0360 790361036203630364
791F1F1F1F
LDRRARRARRARRA
A,C
0365 £6 OF AND
0367 5F LD
OFH
E,A
0368 CD 0115 CALL set user
;Stackpointer laden;User/Disknummer;retten;A = User/Disknummer;A um 4 Bits rotieren
;Die oberen 4 BitsJbilden die Disk- die;unteren 4 Bits die;Usernummer;Disknummer aus-;maskieren;E = gewünschte User-;nummerJUsernummer setzen
89
CCP-Listina
036B CD OOB8 CALL reset_system
036E 32 07AB LD
0371 C1
03720373
79E6 OF
037E B7
POP
LDAND
0375 32 07EF LD
0378 CD OOBD CALL037B 3A 0007 LD
OR
037F C2 0398 JP
(submit_flag),A
BC
A,COFH
(ccp_disk),A
select_diskA, (§cmd_buf f er-t-1
A
NZ,execute_cmd
BDOS inzustandDisk A:A - FFH,
den Ausgangs-bringen undeinloggen.falls ein
kön-Sub-
$-File gefundenwurde, (siehe BDOS1 logical_select 'Wert merken, esnte sich um einmit-FilehandelnUser /DisknummerzurückA = NummerUsernummer ausmask-ierenDisknummer als CCP-Disk speichernDisk selektierenA = Anzahl der Zei-chen im BufferSind bereits Zeichenim Buffer vorhanden ?J: Zeichen als Auto-befehl auffassen undden Befehl ausführen
; CCP-Neustart nach Ausführung eines CCP-Befehls
ccp_prompt:*
0382 31 07AB LD0385 CD 0098 CALL
0388 CD 01 DO CALL
038B C6 41
038D039003920395
CD 008C3E 3ECD 008CCD 0139
ADD
CALLLDCALLCALL
SP,stack_areaprint_crlf
get_disk_code
A, 'A1
conout
conoutget_command__line
Stackpointer ladenNeue AusgabezeilebeginnenAktuelle Disknummerholen-i- ASCII-Wert von 'A1
ergibt Buchstabenzwischen 'A1 und 'P1
Buchstaben ausgeben1 > 'ausgebenBefehlszeile holen(entweder von derConsole oder auseinem Submit-File)
90
CCP-Listing
Im §cmd_buffer stehende Befehlszeile interpretieren undausführen
execute cmd:
0398039B
03B1
03B4
03BC03BD03BE03BF03CO
11 0080CD 01D8
LD DE,§bufferCALL set dma
039E CD 01 DO CALL get_disk_code
03A1 32 07EF LD (ccp_disk),A
03A4 CD 025E CALL setup_fcb
03A7 C4 0209 CALL NZ,command error
03AA 3A 07FO LD A,(file_disk_no)
03AD B7 OR A
03AE C2 06A5 JP
CD 032E
21 03C1 LD
7E23666FE9
LDINCLDLDJP
NZ,execute_program
CALL search__ccp_cmd
HL,cmd_adresses
03B703B803BA03BB
5F1 6 00191 9
LDLDADDADD
E,AD,0HLfDEHL,DE
A,(HL)HLH,(HL)L,A(HL)
DE -> §bufferDMA-Adresse auf§buffer setzenAktuelle BDOS-Disk-nummer holenund als CCP-DiskspeichernEingegebenen Befehlals Filenamen auf-fassen und in deninternal_fcb über-nehmenFehler, falls einmehrdeutiger Datei-name (also mit '*'oder '?') angegebenwurdeWurde eine Diskbe-zeichnung vorange-stellt ?Dann ist die 'file_disk_no" nicht 0(siehe setup_fcb)J: Befehl als File-namen eines Programmsauffassen und diesesProgramm ausführenN: Wurde einer derCCP-Befehle benutzt ?HL -> Tabelle derStartadressen derCCP-BefehlsroutinenDE = Befehlsnummer
Befehlsnummer zweimalaufaddieren ergibtZeiger auf die Adres-se des gewünschtenBefehlsLSB der Adresse ladenZeiger +1MSB der Adresse ladenHL = AdresseBefehlsroutine aus-führen
91
CCP-Listing
; Adress-Tabelle der in der cmd_table aufgeführten; Befehle.; Der von 'search_ccp_cmd' gelieferte Wert entspricht; der Position dor Adresse in dieser Tabelle
cmd adresses:
03C103C303C503C703C903CB03CD
0477051F055D05AD0610068E06A5
def v;def wdef wdef wdef wdef wdef w
direratypesaverenuserexecute_program
'DIR1
'ERA''TYPE1
'SAVE1
'REN''USER'Nicht erkannter Be-fehl, der Befehlwird als Programm-name aufgefasst unddas entsprechendeProgramm gestartet
; Beim Vergleich der beiden Seriennummern von CCP und BDOS; wurde eine Abweichung entdeckt.; Diese Routine hier lässt den CCP 'abstürzen1
wrong_serial
03CF03DO03D1
21F376
defb 21hDIHALT
03D2 22 0000 LD
03D5 21 0000 LD03D8 E9 JP
(ccp),HL
HL,ccp(HL)
;'LD HL,';HL mit den Befehlen;'DI' und 'HALT';laden.;Diese Befehle beim;CCP-Start eintragen;und zum CCP-Start;springen
'r.* :
UPRO für TYPELesefehler melden, 'READ ERROR' ausgeben
read error:
03D903DC
01 03DFC3 OOA7
LD BC,txt_read_error ;BC -> TextJP print_text ;Text ausgeben
txt__read_error•
03DF 5203E9 00
defm 'READ ERROR1
defb 0
92
CCP-Listing
; UPRO für DIR und REN; File nicht gefunden, 'NO FILE1 ausgeben
no file:
03EA03ED
01 03FOC3 OOA7
txt_no_file:•
03FO 4E03F7 00
LD BC,txt_no_fileJP print_text
defm 'NO FILE1
defb 0
;BC -> Text;Text ausgeben
; UPRO für USER und SAVE; Die nach dem Befehl angegebene Nummer auswerten.
; I: ?buffer_address zeigt auf das, dem Befehlswort folgende: Zeichen
; O: A = Nummer, falls sie eindeutig ist und im Bereich; von 0 bis 255 liegt.; Sprung nach 'command_error' sonst?get_number:
03F8 CD 025E CALL setup_fcb
03FB03FE03FF
04020405
3A 07FOB7
LDOR
C2 0209 JP
21 07CE01 OOOB
LDLD
get_number_loop:
04080409040B
040E040F
041 1
041 3
7EFECA
23D6
FE
D2
200433
30
OA
0209
LDCPJP
INCSUB
CP
JP
spaZfg.
HL'0'
OAH
NC,
; Zeichen ab ?buffer_;address in den inter-;nal_fcb übernehmen
A,(file_disk_no) ;Wurde eine Diskbe-A ; Zeichnung gefunden?NZ,command_error ;J: Keine Ziffer an-
jgegeben, Fehler;N: HL -> Ziffern
HL,internal_filenameBC,11 JB = 0 (Zwischensumme)
;C = 11 (Ziffern-: zähler)
HL) ;Nächste Ziffer holen;Leerzeichen gefunden?
Z,get_number_exit ;J: Restliche Zeichen;des Filenamens über-jprüfen;N: Zeiger +1JASCII-Wert in Dezi-Jmalwert umrechnenJLiegt der Wert im;Ziffernbereich ?
NC,command_error ;N: Keine Ziffer ge-;funden, Fehler
93
CCP-Listing
0416 57 L D D,A
041 7041 8
041A
041D041E041F04200421
04220425
04260429
042A042D
042E042F
78E6 EO
C2 0209
7807070780
DA 020980
DA 020982
DA 020947
ODC2 0408
LDAMD
JP
LDRLCARLCARLCAADD
JPADD
JPADD
JPLD
DECJP
A, BOEOH
NZ
A,
A,
c,A,
c,A,
c,B,
CNZ
Command erro
B
3
command errorB
command errorD
command errorA
,qet number 1
* 9
0432 C9
;Neuen Ziffernwert;speichern;A -= Zwischensumme;Ist die Zwischensumme;bereits > 31 ?;J: nit der neuen Zif-;fer würde sich ein;Wert von mindestens;320 ergeben, Fehler.;N: A - Zwischensumme;*2;*4;*8;+ Zwischensumme;- Zwischensumme;Überlauf (>255) ?;J: Fehler;N:+ Zwischensumme; «= Zwischensumme *;Überlauf (>255) ?;J: Fehler;Zwischensumme * 10;+ neue Ziffer ergibt;die neue Zwischen-;summe;Überlauf (>255) ?;J: Fehler;N: Neue Zwischen-;summe speichern;Ziffernzähler -1JWeiter, bis Ziffern-;zähler = 0
10
RET
; Leerzeichen gefunden, Ziffernzähler noch größer 0•
get_number_exit:
0433 7E
043404360439043A043B
043E043F
FE 20C2 020923ODC2 0433
78C9
LD
CPJPINCDECJP
LDRET
A,(HL)
spaceNZ,command_errorHLC
JNächstes Zeichen;holen;Leerzeichen ?;N: FehlerJJ: Zeiger +1;Ziffernzähler -1
NZ,get_number_exit;Weiter, bis Ziffern-Jzähler = 0
A, B JA = Nummer
94
CCP-Listing
; UPRO für ' load_and_execute ' zur Einsetzung des Filetyps 'COM1
; in den angegebenen Filenamen.•r•r 3 Bytes von (HL) nach (DE) kopieren
I: DEHL
/•/•tmove_3_bytes:*
0440 06 03•t
- Zieladresse- Quelladresse
LD B,3 ;B ist Zähler
; B Bytes von (HL) nach (DE) kopieren•/; I: B = Anzahl der zu kopierenden Bytes; DE - Zieladresse; HL - Quelladresse
move_b_bytes:
044204430444044504460447044A
7E12231305C2 0442C9
LDLDINCINCDECJPRET
A,((DEHLDEBNZ,
HL)),A
mov
;Byte holen;Byte speichern;Quellzeiger +1;Zielzeiger +1;Zahler -1jWeiter, bis Zähler -0
; UPRO für DIR; Einzelnes Byte aus dem §buffer holen
I: A-fC = relative Position des gewünschten Bytes innerhalbdes übuffer
O: A = Byte an der Position (§buffer + A + C)
get_byte_from_buffer:•
044B 21 0080 LD HL,§buffer044E 81 ADD A,C044F CD 0259 CALL add_hl_a0452 7E LD A,(HL)0453 C9 RET
;HL -> §bufferJA = A+C;HL = HL + A;Byte holen
95
CCP-Listing
Neue Disk selektieren, falls es nicht die aktuelleCCP-Disk ist.
select new disk:
04540455
0458045B045C045D
045E0461
04620463
••/; Nach
AF32
3A
C83D
21BE
C8C3
07CD
07FO
07EF
OOBD
Anwahl; wieder•/select•04660469046A046B
046C046F
047004710474
die
_old_di
3AB7C83D
21BE
C83AC3
07FO
07EF
07EFOOBD
XORLD
LDORRETDEC
LDCP
RETJP
eineralte Di
sk:
LDORRETDEC
LDCP
RETLDJP
A(internal fcb),A
A, (file disk no )AZA
HL,ccp disk(HL)
Zselect disk
neuen Disk (übersk selektieren.
A, ( file disk no )AZA
HL,ccp disk(HL)
ZA, ( ccp_disk)select disk
A = 0Diskcode des FCB aufNull setzen, da dieCCP-Disk jetzt ange-wählt wird und damitzur aktuellen DiskwirdWurde wirklich eineneue Disk verlangt ?N: FertigJ: Diskcode in Disk-nummer umwandelnund mit der aktuellenCCP-Disk vergleichen.Ist die neue Diskgleich der CCP-Disk ?J: FertigN: Neue Disk selek-tieren
select new disk)
;Wurde eine neue DiskJangewählt ?;N: Fertig;J: Diskcode in Disk-Jnummer umrechnen;ist die neu ange-;wahlte Disk gleich;der CCP-Disk ?;j; Fertig;N: CCP-Disk wieder;selektieren
96
CCP-Listing
*•< ;" . >." -?-
•-«p
. **** DJR
•r; Directory ausgeben
dir:
0477 CD 025E CALL setup_fcb
047A CD 0454 CALL select new disk
047D 21 07CE LD
0480 7E
0481 FE 20
LD
CP
;Die eventuell dem;DIR-Befehl folgende;Disk- und/oder File-;bezeichnung in den;internal_fcb über-;nehmen;Neue Disk, falls an-jgegeben, selektieren
HL,internal_filename;HL -> Nach 'DIR1 fol-gende Filebezeichnung;Erstes Zeichen dieser;Filebezeichnung holen;Wurde eine Filebe-; Zeichnung angegeben ?;J: Zum internal_fcb;passende Directory-;Einträge anzeigen
;N: 'DIR1 ohne File-;bezeichnung ent-;spricht einem; ' DIR *.* ' .; internal_fcb ent-;sprechend vorbe-;reiten
Filenamen und Filetyp im internal fcb mit '?' füllen
0483 C2 048F JP
A,(HL)
space
NZ,dir file
0486 06 OB LD B,11 ;8 Zeichen Filenamen;und 3 Zeichen File-;typ mit '?' füllen
set_wildcard_loop:
0488048A048B
36 3F2305
LDINCDEC
(HL) ,HLB
''
048C C2 0488 JP
einsetzen;FCB-Zeiger +1;Zähler -1;Weiter, bis Zähler
NZ , set_wildcard_loop=0
97
CCP-Listing
Alle auf den internal_fcb passenden Directory-Einträgeanzeigen.
dir file:
048F 1E 00
0491 D50492 CD OOE9
L D E,0
PUSH DECALL search fcb
0495 CC 03EA CALL Z,no file
;Spaltenzähler auf 0;setzen;Spaltenzähler retten;Ersten passenden Dir-;ectory suchen;Nichts gefunden ?;J: 'NO FILE' melden
r•t; Nächsten passenden Directory-Eintrag anzeigen•t; I: Flags vom letzten search_next gesetzt
dir loop:
0498 CA 051B049B 3A 07EE
049E OF049F OF04AO OF
04A604A9
JPLD
RRCARRCARRCA
04A1 E6 6004A3 4F
04A4 3E OA
ANDLD
LD
CD 044B17
CALLRLA
04AA DA 05OF JP
Z,dir_exitA, (return code)
;Wurde ein nächster;Eintrag gefunden ?;N: Fertig;Directory-Code vom; letzten 'search_next';holen^Dreimal nach rechts;rotiert, entspricht;einer Multiplikation;mit 32. Dies ist dann;die relative Position;des gefundenen Ein-Jtrags im §bufferjuntere 5 Bits löschen;C = Position des Ein-;trags;A = relative Position;des 'SYS'-Flags in-;nerhalb des Eintrags.; 'SYS'-Flag holen
get_byte_from_buffer;'SYS'-Flag ins Carry-;Flag schieben.;'SYS'-Flag gesetzt ?
C,entry_is_sys ;J: 'SYS'-Files werden;nicht angezeigt
060HC,A
A,10
98
f.». IT. .
04AD04AE04AF04BO04B1
D17ß1CD5E6 03
POPLDINCPUSHAND
DEA, EEDE3
04B3 F5
04C404C604C9
PUSH AF
04B4 C2 04CC JP NZ , dir_next_in_
04B7 CD 0098 CALL print_crlf
04BA C5 PUSH BC
04BB CD 01 DO CALL get_disk_code
04BE C1 POP BC
I A I04BF C6 41 ADD A,'A
04C1 CD 0092 CALL conout be
3E 3A LDCD 0092 CALLC3 04D4 JP
' • 'r
conout__bcshow file
CCP-Listing
;Spaltenzahler zurück;A - SpaltenzählerjSpaltenzähler +1jSpaltenzähler rettenJA = Spaltenzählerjmodulo 4;A rettenjSpaltenzähler modulo;4 gleich Null ?jN: Gefundenen Eintragjinnerhalb der selbenjZeile ausgeben
line;J: Es v/erden nur 4;Einträge pro Zeilejangezeigt.;Neue AusgabezeilejbeginneenjEintrags-Position;rettenjAktuelle Disknummerjholen;Eintrags-PositionjzurückjDisknummer + 'A1 er-jgibt Diskbezeichnung;('A' - 'P')jDiskbezeichnung aus-;geben, BC dabei ret-;ten;Doppelpunkt danachJausgebenjFilenamen anzeigen
j Gefundenen Eintrag innerhalb der selben Zeile anzeigen
dir__next_in_line:•
04CC CD OOA2 CALL print_space04CF 3E 3A LD A, ' : '04D1 CD 0092 CALL conout bc
jLeerzeichenJund Doppelpunkt alsjTrennung ausgeben
99
CCP-Listing
; Filenamen und Filetyp des gefundenen Eintrags anzeigen»show file:
04D4 CD OOA2 CALL print_space
04D7 06 01 LD
;Leerzeichen voran-; stellen;B ist die relative;Position des nächstenAuszugebenden Zei-;chens innerhalb des;Eintrags. (Position;0 des Eintrags ist;die Usernummer i)
i} Nächstes Zeichen des Filenamens ausgeben
; C ist immer noch die relative Position des Eintrags inner-; halb des §buffers
dir next char:
04D9 78
04DA04DD04DF04E1
04E404E5
04E6
04E8
04EB
04ED04FO04F2
CDE6FEC2
F1F5
FE
C2
3E«*
CDE6FE
044B7F2004F9
03
04F7
09
044B7F20
CALLANDCPJP
POPPUSH
CP
JP
LD
CALLANDCP
ge07spNZ
AFAF
3
NZ
A,
ge07sp
04F4 CA 050E JP
LD A,B ;A - relative Zeichen-jposition;Nächstes Zeichen aus;dem Buffer holen
get_byte_f rom_buf f er;Bit 7 ausmaskieren
e ;Leerzeichen ?NZ,dir_print_char ;N! Zeichen normal
;ausgeben;Spaltenzähler mod 4; zurück und wiederJretten;Sind wir in der letz-;ten Spalte ?
NZ,dir_print_space;N: Leerzeichen normalJausgeben;J: Erstes Zeichen vomJFiletyp holen
get_byte_from_bufferJBit 7 löschen
e ;lst es ein Leer-;zeichen ?;J: Dann existiert;kein FiletypJNächsten Eintrag;suchen
Z ,get_next_dir_entry
100
CCP-Listing
; Leerzeichen ausgeben
dir print_space:
04F7 3E 20 LD A,space ;A - Leerzeichen
Zeichen des Filenamens ausgeben
dir_print_char :•t04F904FC04FD
•9
CD 00920478
04FE FE OC
CALLINCLD
CP
05000503
0505
0508
D2FE
C2
CD
050E09
04D9
OOA2
JPCP
JP
CALL
050B C3 04D9 JP
conout__bcBA,ß
;Zeichen ausgeben; Zeichenposition +1;A - Neue Zeichen-;position
12 """ ' "' """" " " ;Ist die neue Position^kleiner als 12 ?;N: Filenamen komplett^ausgegeben^Nächsten Filenamen^suchen
NC,get_next_dir_entry9 ;Ist die neue Position
;das erste Zeichen des;Filetyps ?
NZ,dir_next_char ;N: nächstes Zeichen;ausgeben;JI Leerzeichen als;Trennung zwischenjFilenamen und File-;typ ausgebenjNächstes Zeichen aus-Jgeben
print_space
dir next char
; Nächsten passenden Eintrag suchen und anzeigen
get__next_dir_entry:
050E F1 POP AF ;Spaltenzähler vom;Stack nehmen
101
CCP-Listing
; Einsprung, falls ein Eintrag mit gesetztem 'SYS1-Flag; gefunden wurde
entry is sys:
050F CD 01 C2 CALL check console
0512 C2 051B JP NZ,dir__exit0515 CD OOE4 CALL search next
0518 C3 0498 JP dir loop
;Steht ein Zeichen von;der Console an ?;(V7urde eine Taste;gedrückt ?);J: DIR abbrechen;N: Nächsten passenden^Eintrag suchen;und anzeigen
; DIR beenden
dir exit:
051B D1 POP
051C C3 0786 JP
DE
reenter__ccp
;Spaltenzähler vom; Stack nehmen; Zurück zum CCP
102
CCP-Listing
; File(s) löschen
era:
051F CD 025E CALL
0522 FE OB
053705380539053B
237EFE 59C2 0382
053E 23
CP
0524 C2 0542 J?
0527 01 0552 LD052A CD OOA7 CALL052D CD 0139 CALL
0530 21 0007 LD
0533 35 DEC0534 C2 0382 JP
INCLDCPJP
INC
setup_f cb
1 1
NZ,era not all
BC,txt_all_ynprint_textget__command_line
HL,§cmd_buffer+1
(IIL)NZ,ccp_prompt
053F 22 0088 LD
H LA,(HL)'Y1
NZ,ccp_prompt
HL
(?buffer adress)
;Angegebenen Filenamen;übernehmen;11 Fragezeichen ge-;funden (ERA *.*) ?;N: Es sollen nicht;alle Files gelöscht;werden;J: Nochmal nachfragen;BC -> 'ALL (Y/N)?1
;Text ausgeben;Antwort als komplette;Zeile holen;HL -> Anzahl der ein-;gegebenen Zeichen;-1 gleich Null ?;N: Es darf nur ein;Zeichen ('Y1 oder;"N 1) eingegeben wer-fen; zurück zum CCP-;Prompt;J: HL -> Zeichen;Zeichen holen;lst es 'Y1
;N: Alles andere wird;als 'N1 interpretiert;Bufferzeiger erhöhen;und abspeichern
,HL
era not all:
0542 CD 0454 CALL select new disk
05450548054B054C054F
11 07CDCD OOEF3CCC 03EAC3 0786
; Text für ERA•t
txt_all_yn:•
0552 41055C 00
LDCALLINCCALLJP
def mdefb
DE,internal_fcbdelete_fileAZ,no_filereenter_ccp
'ALL (Y/N)?'0
;Evtl. angegebene Disk;selektieren;DE -> FCB;File(s) löschen;Fehlercode = 255 ?JJ: 'NO FILE' melden;zurück zum CCP
103
CCP-Listing
**** TYPE•t; (ASCII-)File ausgeben
type:
055D CD 025E CALL
0560 C2 0209 JP
0563 CD 0454 CALL
0566 CD OODO CALL
0569 CA 05A7 JP056C CD 0098 CALL
056F 21 07F1 LD0572 36 FF LD
setup_fcb ^Angegebenen Filenamenjübernehmen
NZ,command_error ;Fehler, falls der;Filenamen nicht ein-jdeutig ist;Angegebene Disk;selektieren;File öffnen;File vorhanden ?;N: Fehler;J: Neue Ausgabezeilejbeginnen;HL -> Zeichenzähler
counter; Zeichenzähler mit;255 vorbesetzen
select_new_disk
open_fcb
Z,type_errorprint crlf
HL,type_char_c(HL),2 5 5
; Nächstes Zeichen lesen und ausgeben
type_loop:
0574 21 07F1 LD0577 7E LD
0578 FE 80
057D057E05810582
E5CD OOFEE1C2 05AO
CP
057A DA 0587 JP
PUSHCALLPOPJP
HL,type_charA,(HL)
128
C,type char
HLread_fcbHLNZ,type_exit
;HL -> Anzahl der vomjaktuellen Record be-;reits ausgegebenen; Zeichen
_counterJA = Anzahl der ausge-Jgebenen Zeichen;schon 128 ZeichenJausgegeben ?;N: Nächstes ZeichenJaus dem Buffer holen;J: Der aktuelle Re-Jcord wurde komplettJausgegeben. NächstenjRecord des Files in;den Buffer laden.JHL retten^Nächsten Record lesenJHL zurückJType abbrechen, falls;ein Lesefehler aufge-Jtreten ist.
104
CCP-Listing
0585 AF0586 77
XORLD
A(HL),A
JA = 0;Vom neu gelesenen Re-;cord wurde noch kein^Zeichen ausgegeben.
Nächstes Zeichen vom Buffer holen und ausgebenA = relative Position des nächsten Zeichens
innerhalb des Buffers
type_char:
058705880583058E058F
059105940597
3421CD7EFE
CACDCD
00800259
1 A
0736008C01C2
INCLDCALLLDCP
JPCALLCALL
059A059D
C2 0786C3 0574
JPJP
(HL)HL,§bufferadd_hl_aA,(HL)eo:
Z,reenter_ccpconoutcheckconsole
NZ , reenter__ccptype_loop
Zeichenzähler +1HL -> BufferHL -> ZeichenZeichen holen'End Of File1 er-reicht?J: Type beendenN: Zeichen ausgebenSteht ein Zeichenvon der Console an ?(Wurde eine Tastegedrückt ?)J: Type abbrechenN: Nächstes Zeichenausgeben
TYPE-Abbruch nach Lesefehler
type_exit:»
05AO 3D05A1 CA 0786
DEC AJP Z,reenter_ccp
05A4 CD 03D9 CALL read error
Fehlercode = 1 ?;J: Ende des FilesJerreicht, es war kein;'echter' Lesefehler;N: 'READ ERROR' mei-;den
; TYPE-Abbruch; fehlerhafter•rtype_error:
bei nicht eindeutigem Filenamen bzw.Parameterangäbe
05A7 CD 0466 CALL select old disk
05AA C3 0209 JP command error
;Alte Disk wieder anJwählen und;fehlerhaften Para-Jmeter ausgeben
105
CCP-Listing
*; spefsave :
05AD
05BO05B1
05B4
05B705BA05BD05BE
05C105C205C5
05C8
05C9
05CC
05CD05CE05DO
.J/-1 v i_i
icherbere
CD 03F8
F5CD 025E
C2 0209
CD 045411 07CDD5CD OOEF
D1CD 0109CA 05FB
AF
32 07ED
F1
6F26 0029
ich au
CALL
PUSHCALL
JP
CALLLDPUSHCALL
POPCALLJP
XOR
LD
POP
LDLDADD
f Disk schreiben
get_number ;
?AF ;setup_fcb ;
NZ, command error ;*t*r
select new disk ;DE, internal fcb ;DE ;delete_file ;
•ft
DE ;make_file ;Z, no space ;
r*f
A ;i*t
(internal record ft]
AF ;•r
L, A ;H,0HL , HL ;
Anzahl der zu spei-chernden Seiten aus-wertenAnzahl rettenFilenamen in den in-ternal_fcb überneh-menFehler, falls derFilenamen nicht ein-deutig ist.Disk selektierenDE -> FCBFCB-Zeiger rettenEvtl. vorhandenesFile gleichen Namensvorher löschen.FCB-Zeiger zurückFile neu anlegen'NO SPACE1 melden,falls die Directoryvoll istA = 0Recordnummer auf Nullsetzen,A
Anzahl der;chernden Seiten;rück;HL = Anzahl
zu spei-zu-
05D1 11 0100 LD DE,?tpa_start
;Anzahl der Records;berechnen (Eine Sei-;te im Speicher ent-Jspricht zwei Records)JDE -> TPA
106
CCP-Listing
; Nächsten Record schreiben; DE -> SpeicherbereichHL = Anzahl der verbleibenden Records
save_loop:
05D405D505D6
1C35CA 05F1
05D9 2B05DA E505DB 21 0080
05DE 19
05DF E505EO CD 01D8
05EA E1
LD A, HOR LJP Z,close_save_file
DEC HLPUSH HLLD HL,128
ADD HL,DE
PUSHCALL
05E3 11 07CD LD05E6 CD 0104 CALL05E9 D1 POP
POP
05EB C2 05FB JP
05EE C3 05D4 JP
HLset dma
DE,internal_fcbwrite_sequDE
HL
NZ,no space
save_loop
Verbleibende Record-anzahl = 0 ?J: Fertig, FileschliessenN: Anzahl -1Anzahl rettenHL - Länge einesRecords in ByteNächste (i) Speicher-adresse berechnenund rettenAdresse des jetzt zuschreibenden Recordssetzen (in DE \)DE -> FCBRecord schreibenNeue Adresse vomStack holenVerbleibende Anzahlzurück'NO SPACE1 melden,falls beim Schreibenein Fehler aufgetre-ten istSonst nächsten Recordschreiben
; File schließen
close save file:
05F1 11 07CD LD05F4 CD OODA CALL05F7 3C INC
05F8 C2 0601 JP
DE,internal_close_fileA
NZ, save exit
fcb JDE -> FCB;File schließen;Fehler beimJSchließen ?;N: Save beenden
1 07
CCP-Listing
; Fehlermeldung 'NO SPACE1 ausgeben
no_space:
05FB05FE
01 0607CD OOA7
LD BC,txt_no_spaceCALL print text
;BC -> Text;Text ausgeben
; Save beenden
save exit:
0601 CD 01D5 CALL set default dma
0604 C3 0786 JP reenter_ccp
;DMA-Adresse auf Stan-jdardwert zurücksetzen; Zurück zum CCP
; Text für SAVE•/txt_no_space:
0607060F
4E00
defm 'NO SPACE1
defb 0
108
I
. **** REN•t; Filenamen ändern
CCP-Listing
ren:
0610 CD 025E CALL
0613 C2 0209 JP
0616061 9061A061D
06230626
06290623
3A 07FOF5CD 0454CD OOE9
21 07CD11 07DD
06 10CD 0442
063A FE 5F
LDPUSHCALLCALL
0620 C2 0679 JP
LDLD
LDCALL
062E06310632
06350637
2AEBCD
FECA
0088
024F
3D063F
LDEXCALL
CPJP
CP
setup_fcb
NZ,command error
A,(file_disk_no)AFselect_new_disksearch fcb
063C C2 0673 JP
;Neuen Filenamen über-;nehmen;Fehler, falls der;Filenamen nicht ein-;deutig ist;Diskcode holen;und retten;Disk selektieren;und Directory auf;neuen Filenamen über-;prüfen. Ist der neuejFilename bereits vor-;handen ?;J: 'FILE EXISTS1 mel-;den;N: Neuen Filenamen;nach rename_fcb ko-jpieren (für BDOS-;Funktion 'rename');16 Bytes;kopieren;HL -> nächstes Buf-; ferzeichen
HL,(?buffer_adress)DE,HL JDE = HLget_next__char ;Nächstes Zeichen
;holen;ist es '=' ?
Z,ren_delimiter_ok;J: Trennungszeichen;in Ordnung;ist es '_' ?;(Dieses Zeichen ist;bei manchen Computern;ein Pfeil nach links);N: Fehler
NZ,ren file not found
NZ,file_exists
HL,internal_fcbDE,rename_fcb
B,16move b bytes
109
CCP-Listing
Trennungszeichen zwischen dem neuen und alten Filenamenist in Ordnung
ren delimiter ok:
063F EB
0640 23
EX
INC
0641 22 0088 LD
DE,HL ;HL -> Trennungs-;zeichen
HL ;HL -> nächstes Zei;chenjZeiger auf das;nächste Zeichen,;für den folgenden;'setup_fcb'-Aufruf;speichern.
(?buffer_adress),HL
«
0644 CD 025E CALL setup_fcb
0647064A
064B064C
064F0650
C2 0673F1
4721 07FO
7EB7
JPPOP
LDLD
LDOR
NZ ,renAF
B, AHL,fil
A, (HL)A
0651 CA 0659 JP
0654 B8
0655 70
CP
LD
Z ,ren_disk_ok
B
(HL),B
0656 C2 0673 JP NZ.ren file not
yAlten Filenamen über-;nehmen;Fehler, falls der;alte Filenamen nicht;eindeutig ist.
found;Diskcode des neuen;Filenamens zurück;und in B speichern;HL -> Diskcode;des alten FilenamensJDiskcode holen.;Wurde beim altenJFilenamens ein Disk-Jcode angegeben ?;N: Diskcode des neuen;Filenamens auch fürJden alten Filenamen;benutzen.;JI Sind beide Disk-;codes identisch ?
;Diskcode des neuen;Filenamens schonmal;speichern.;Fehler, falls die;beiden Filenamen un-;terschiedliche Disk-;codes haben,
found
110
CCP-Listing
; Die Diskcodes der beiden Filenarnen sind verträglich.; Diskcode des neuen Filenamen speichern.?ren_disk_ok:
0659 70 LD065A AF XOR065B 32 07CD LD
(HL),BA(internal fcb),A
065E CD OOE9 CALL search fcb
0661 CA 066D JP , Z,ren no file
06640667066A
1 1CDC3
07CD01 OE0786
LDCALLJP
DE, internal_f cbrename_f ilereenter_ccp
jDiskcode speichern;A - 0;Diskcode des alten;Files auf Null setzen;(Die richtige Disk;wurde schon selek-;tiert i);Alter Filenamen vor-jhanden ?;N: 'NO FILE1 melden
;J: DE -> FCB;BDOS-Aufruf;Zurück zum CCP
t•9*9 'NO FILE' melden
ren no file:
066D0670t
CDC3
• Fehler:
03EA0786
Alter
CALLJP
Fi
no_filereenter_
lename ni
•9
_ccp ;
cht vorhanden
;'NO FILE' ausgeben;Zurück zum CCP
renf ilenotf ound:
0673 CD 0466 CALL selectolddisk
0676 C3 0209 JP command error
JAlte Disk wieder;selektieren;und Fehler melden
; Fehler: Neuer Filename bereits vorhanden•ifile_exists:»9
0679 01 0682 LD BC,txt_file_existsJBC -> Text067C CD OOA7 CALL print_text ;Text ausgeben067F C3 0786 JP reenter_ccp ;Zurück zum CCP
txt file exists:
0682 46068D 00
defm 'FILE EXISTS1
defb 0
1 1 1
CCP-Listing
; **** USER•f; Neuen Userbereich anwählen
user:•
068E069106930696
CD 03F8FE 1 0D2 02095F
CALLCPJPLD
0697 3A 07CE LD069A FE 20 CP
069C CA 0209 JP
get_number ;Neue Usernummer holen16 ;Nummer > 15 ?NC,command_error ;J: FehlerE,A ;E - Usernummer
;Wurde v/irklich eine;Nummer angegeben ?;J: Dann steht sie im;'internal_filename'
A, (internal filename)space
Z , command_error
069F CD 0115 CALL set user
06A2 C3 0789 JP reenter new disk
;Steht dort ein Leer-jzeichen ?;J: Keine Nummer an-gegeben, Fehler.;N: Neue Usernummer; setzen;Zurück zum CCP ohne;Disk-Selektierung;(es wurde ja auchjkeine neue DiskJangewählt)
1 1 2
CCP-Listing
; Der eingegebene Befehl ist keiner der eingebauten; CCP-Befehle.; Befehl als Filename eine Programms interpretieren und; dieses Programm laden und ausführen.rexecute_program:
06A5 CD 01F5 CALL compare_serial ;Seriennummern des CCP;und BDOS miteinanderDergleichen und bei;Ungleichheit 'System-;absturz' auslösen.;Wurde ein Filenamenjangegeben ?
A,(internal_filename)space ;Ist also das erste
;Zeichen des 'inter-;nal_filename' kein;Leerzeichen ?;J: Programm laden undJausführen
NZ tload_and_execute
06A806 AB
3A 07CEFE 20
LDCP
06AD•/•
C2 06C4 JP
; Der Befehl ist kein Filename.; Wurde nur eine Diskbezeichnung angegeben ?
06BO 3A 07FO LD06B3 B7 OR
06B4»r
CA 0789 JP
A,(file_disk_no) ;lst eine Diskbe-A ;Zeichnung erkannt
;worden ?Z,reenter_new_disk;N: Zurück zum CCP
Der Befehl ist eine DiskbezeichnungNeue 'ccp_disk' anwählen.
06B7 3D DEC A
06B8 32 07EF LD (ccp_disk),A
06BB CD 0129 CALL set_disk
06BE CD OOBD CALL select disk
06C1 C3 0789 JP reenter new disk
JJ: Diskcode in Disk-Jnummer umwandelnJund als neue CCP-Disk;speichern;Neue Disknummer in;§disk speichern;und neue Disk selek-;tieren;Zurück zum CCP
1 13
CCP-Listing
Als Befehl wurde weder einerDiskbezeichnung angegeben.Es muß ein Filename sein.
der CCP-Befehle noch eine
load and execute:
06C406C7
111A
07D6
06C8 FE 20
LDLD
CP
06CA C2 0209 JP
06CD06CE06D1
06D206D5
D5CDD1
21CD
0454
07830440
PUSHCALLPOP
LDCALL
;DE -> Filetyp des;angegebenen Files
DE,internal_filetypeA,(DE)
space
NZ, command error
DEselect_new_diskDE
HL,default_typmove 3 bytes
06D8 CD OODO CALL open fcb
;Wurde ein Filetyp;mit angegeben ?;Ist also das erste^Zeichen des File-;typs kein Leerzei-;chen ?;J: Fehler, der File-;typ wird immer vom;CCP eingetragen
;Filetyp-Zeiger retten;Disk selektieren; Zeiger zurück
;HL -> Filetyp 'COM1
;'COM' als Filetyp;einsetzen;File öffnen. Ist dasJFile vorhanden ?
06DB CA 076B JP
;N: Alte Disk wiederJanwählen und Fehler;melden
Z,transient not found
; Programm laden und ausführen
06DE 21 0100 LD HL,?tpa start-»."t *** „.'U l -
;Programme werden im-;mer ab dem '?tpa_;start1 geladen
114
CCP-Listing
r
j Nächsten Record des Programms laden.j HL - Ladeadresse•iload next record:
06E106E206E3
06E606E9
06EC06EF06FO
06F706F806F906FA06FB
E5EBCD 01D8
11 07CDCD OOF9
06F3 19
7D937C9AD2 0771
PUSHEXCALL
LDCALL
C2 0701 JPE1 POP11 0080 LD
ADD
06F4 11 0000 LD
LDSUBLDSBCJP
06FE C3 06E1 JP
HLDE, HLsetdma
DE, internalread sequ
jLadeadresse rettenJDE - Ladeadresse;DMA-Adresse - Lade-jadresse setzen
fcb ;DE -> FCB^Nächsten Record zurjDMA-Adresse laden.jFehler ? (Lesefehler;oder Ende desjFiles ?);J: Ende des Ladevor-;gangs
NZ,setup_parametersHL ;N: Ladeadresse zurückDE,128 ;DE - Länge eines Re-
;cordsHL,DE ;Neue Ladeadresse be-
;rechnenDE,ccp ;DE = CCP-Startadresse
;Würde das Laden des^nächsten Records denJCCP überschreiben ?;lst also die neuejLadeadresse größerJoder gleich der CCP-jStartadresse ?JJ: 'BAD LOAD' melden
A,LEA,HA,DNC,bad load
load_next_record ;N: Nächsten Record; laden
; Beim Lesen des Records ist ein Fehler aufgetreten
setup_parameters:•
0701 E1 POP
0702 3D DEC
0703 C2 0771 JP
HL
A
NZ,bad load
jLadeadresse vom Stack;nehmen^Fehlercode = 1 ?;(Ende des Files er-Jreicht ?);N: 'BAD LOAD' melden
1 1 5
CCP-Listina
; Das Programm wurde vollständig geladen.; Jetzt müssen noch die eventuell vorhandenen Parameter; aufgearbeitet werden.•
0706 CD 0466 CALL select old disk
0709 CD 025E CALL setup_fcb •
HL,file_disk_noHLA,(HL)(internal_fcb),A
A,16
070C070F0710071 1
21E57E32
07FO
07CD
LDPUSHLDLD
0714 3E 10 LD
0716 CD 0260 CALL setup_fcb_offset0719 E1 POP HL
071A 7E LD-i W v »->. ,v*H.->-. ••• "
071B 32 07DD LD
071E AF
A,(HL)
(rename_fcb),A
XOR A
071F 32 07ED LD
07220725
0728072A
1 121
06CD
005C07CD
210442
LDLD
LDCALL
(internal record
DE,?default_fcbHL,internal_fcb
B,33move_b_bytes
;Alte Disk wieder an-;wahlen
Parameter in den in-ternal_fcb übernehmenHL -> DiskcodeZeiger rettenDiskcode in deninternal_fcb über-nehmenZweiten Parameternach internal_fcb+16übernehmenZeiger auf DiskcodezurückDiskcode des zweitenParametersim dazugehörigen fcbspeichernA = 0Recordnummer deszweiten fcbs aufNull setzen,ADie beiden Parameterwerden dem Programmim '?default_fcb' zurVerfügung gestelltZum '?default fcb1
werden vomnal_fcb!
33 Byteskopiert
inter-
116
CCP-Listing
. f A
; Die im §cmd__buffer; Programm auch noch; Dazu muß zuerst die; festgestellt v/erden
stehenden Parameter werden demim §buffer zur Verfügung gestellt.Anfangsadresse der Parameter im Buffer
072D 21 0008 LD HL, §cmd_buf f er+2 ; HL -> Befehlsbuffer
search_parameters:
0730 7E
0731 B7
LD
OR
0732 CA 073E JP
0735 FE 20 CP0737 CA 073E JP
073A 23 INC073B C3 0730 JP
A,(HL) jNachstes Zeichen;holen
A ;Ende der Zeile er-;reicht ?
Z , setup_cmd__buf f er; J: Es wurden keine;Parameter angegeben
space ;Leerzeichen ?Z,setup_cmd_buffer;J: Es ist das Ende
;des Programmnamens;und damit der Anfang;der Parameter er-;reicht.
HL ;N: Zeiger +1search_parameters ^Nächstes Zeichen
;überprüfen
•/; Parameter im §buffer zur Verfügung stellen
setup cmd buffer:/073E 06 00
0740 11 0081
•/
LD
LD
B,0
DE, §buf f er+l
; Zeichenzähler aufjNull setzenJZeichen ab §buffer+1;ablegen
setup cmd buffer loop:v/0743 7E
0744 12
0745 B7
0746 CA 074F
0749 04074A 23074B 13
LD
LD
OR
JP
INCINCINC
A, (HL)
(DE), A
A
Z , run_transient
BHLDE
; Zeichen aus Befehls-Jbuffer holen;und im §buffer ab-; speichern;Ende der Zeile er-;reicht ?;J: Programm starten
;N: Zeichenzähler +1JZeiger +1TZeiger +1
074C C3 0743 JP
^Nächstes Zeichen'f übernehmen
setup_cmd_buffer_loop
1 17
CCP-Listing
f
; Anzahl der Parameterzeichen abspeichern und das geladene; Programm starten.
run_transient:i074F 73 LD
0750 32 0080 LD
A,B
(§buffer),A
0753 CD 0098 CALL print_crlf0756 CD 01D5 CALL set_default_dma
0759 CD 011A CALL set drv usr
075C CD 0100 CALL ?tpa_start
A = Anzahl der ko-pierten ZeichenDiese Anzahl wirdam Anfang des §buf-fers gespeichert.Neue Zeile beginnenDMA-Adresse auf Stan-dardwert setzenDisk- und Usernummerfür den nächstenWarmstart in §diskspeichern (Damit kannauch das Programm er-kennen, 'woher' eskam)Programmstarten,Rückkehrmit 'RET1
kann
mit 'CALL'so daß einezum CCP aucherfolgen
; Ende eines Programms mit 'RET1
t075F 31 07AB LD SP,stack_area
0762 CD 0129 CALL set_disk
0765 CD OOBD CALL select_disk
0768 C3 0382 JP ccp_prompt
' I ~ i. »-. C" . "
JStackpointer neu;setzen;CCP-Disknummer in;§disk speichern;CCP-Disk wieder; selektieren;und zum CCP-Prompt; zurückspringen
; Fehler: Gewünschtes Programm nicht gefunden•itransient_not_found:•/
076B CD 0466 CALL select_old_disk ;Alte Disk wieder; selektieren
076E C3 0209 JP command_error ;und Fehler melden
1 18
CCP-Listing
; Fehler beim Laden eines Programms, 'BAD LOAD1 ausgeben; (Lesefehler oder Programm zu groß)
bad load:
077107740777
01CDC3
077AOOA70786
LDCALLJP
BC, txt_bad__loadprint_textreenter ccp
;BC -> Text;Text ausgeben;Zurück zum CCP
txt bad load
077A0782
4200
•t
defm 'BAD LOAD1
defb 0
; Vom CCP eingesetzter Filetyp für Anwenderprogramme•/default_typ:
430783 defm 'COM1
; Wiedereintritt in den CCP nach Anwahl einer neuen Disk
reenter_ccp:T0786 CD 0466 CALL select old disk ;Alte CCP-Disk wieder
Janwählen
; Wiedereintritt in den CCP•
reenter_new_disk:
CD 025E CALL setup_fcb0789
078C 3A 07CE LD078F D6 20 SUB
0791 21 07FO LD0794 B6 OR0795 C2 0209 JP
0798 C3 0382 JP
^Eventuell weitere;Parameter übernehmen.;Sind noch weitere;Parameter vorhanden ?JDann steht entweder; im internal_filename
A, (internal_filename)space
HL,file_disk_no(HL)NZ,command_error
ccp_prompt
;ein von "Leerzeichen1
Verschiedenes Zeichen;oder;es wurde eine Disk-;bezeichnung erkannt.;J: Dies ist ein;Fehler.;N: Zurück zum CCP-;Prompt
1 1 9
CCP-Listing
Stackbereich für CCP-Funktionen (8 Stufen)Da der Stack beim 8080 (bzw. Z80) nach 'unten1 wächst,steht das Label hinter den Daten.
079B 00•istack area:
defs 16,0
tJ.i
;Label für den Stack-Bereich
Parameterbereich für CCP-Funktionen
; Flag, vom BDOS-Aufruf 'Reset Disk System' kommend, ob auf; dem Laufwerk A: ein Filenamen existiert, der mit '$' be-; ginnt.; Falls dieses Flag gesetzt (-FFH) ist, wird versucht die; nächste Befehlszeile vom Submit-File '$$$.SUB' zu lesen.
; - FFH, falls ein solcher Filename existiert; - OOK, sonst
submit_flag:i07AB 00 defb 0
; File Control Block für das Submit-File $$$.SUB; Da der Diskcode im FCB auf 0 gesetzt ist, wird dieses; File auf der aktuellen Disk erwartet.
submit fcb:
07 AC
07AD
07B5r - •-07B8
07B9
00
24
53
00
00
defb
def m
defm
defb
defb
0
u? ff* ff*^b »p \n
'SUB1
0
0
submit fcb na:
07BA 00 defb 0
;Diskcode
;Filename
JFiletyp
;Extendnummer
j'Not altered'-Flag
f
il
120
CCP-Listing
submit rec count:
07BB 00
07BC 00
defb 0
defs 16,0
;Anzahl der Records
current submit rec:
07CC 00 defb 0
;Blocktabelle
;Aktuelle Recordnummer;für Leseoperation
w
•r Interner File Control Block für die Befehls- und; Parameterverarbeitung
internal fcb:
07CD 00 defb 0
internal filename:
07CE 00 defs 8,0
internal_filetype:
07D6 00
07D9 00
defs 3,0
defs 4,0
jDiskcode
;Filename
jFiletyp
jExtendnummer etc
; Start des zweiten FCBs für die ' Rename; oder Blocktabelle des internal fcb
-Funktion
rename fcb:
07DD 00 defs 16,0
internal record
07ED 00 defb 0 ;Aktuelle Recordnummer;zum internal fcb
121
CCP-Listing
Fehlercode nach BDOS-Aufrufen
return code:
07EE 00 defb 0
CCP-Disknummer
ccp_disk:
07EF 00 defb 0
; Diskcode bei der Parameterverarbeitung; (siehe setup fcb)
file disk no:
07FO 00 defb 0
*
; Anzahl der bereits ausgegebenen Zeichen eines Records; wahrend TYPE (siehe 'TYPE1)
type_char_counter:
07F1 00 defb 0
; Füllbytes, damit der CCP genau 8 Speicherseiten; (0800H Bytes) belegt
07F2 00 defs 14,0
; Startadresse des BDOS bzw. der BDOS-Seriennummer; (siehe BDOS-Sourcelisting)
bdos:
END
122
BDOS-Listing
BDOS Source-Listingr*•
r•/; Dies sind Equates für die verschiedenen, vom BDOS genutzten; ASCII-Werte "
00030005000700080009OOOAGOOD0010001 10012001 3001500180020007F
ctrlcctrlebellbacktabIfcrctrlpxonctrlrxoffctrluctrlxspacedel
equequequequequequequequequequequequequequequ
35789
1 01 3161 718192124i i
1 27
;CTRL-C;CTRL-E
JCTRL-P;CTRL-Q;CTRL-R;CTRL-S;CTRL-U;CTRL-X
Anzahl der vom BDOS unterstützten Funktionen
0029 = no of funcs equ 41
; BDOS-Versionsnummer•t0022 = version_#•
equ 22h ;CP/M 2.2
Warmstart-Adresse
0000 ?boot equ OOOOh
Adresse des IOBYTE
0003 = §io_byte equ ?boot 0003h
; Startadresse des Standard-Diskbuffers
Übuffer equ ?boot + 0080h0080
123
BDOS-Listinq
f; Startadressen der einzelnen; BIGS-Sprungleiste•
• 'b '; BIOS•
OEOO
OE03
OE06
OE09
OEOC
OEOF
OE12
OE15
OE18
OE1B
OE1E
OE21
OE24
OE27
OE2A
OE2D
OE30
am Labelanfang,-Adresse •
b_cboot
b wboot
b const
b conin
b_conout
- b_list
b punch
b_reader
b_home
b_seldsk
b settrk
b setsec
b_setdma
b read
b write
* b_listst
b_sectrn
kennze
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
BIOS-Funktionen in
ichnet das
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
bios +
Label als
0
3
6
9
12
15
18
21
24
27
30
33
36
39
42
45
48
124
BDOS-Listing
Relative Positionen der verschiedenen FCB-Daten innerhalbdes FCB bzw. Directory-Eintrags.
0009
oooc
GOOD
OOOE
OOOE
0010
0020
pos__ro
pos_ex
pos_s1
pos_eg
pos_na
OOOF - pos_rc
pos_dx
pos_cr
equ
0021 - pos_rO
equ
equ
equ
equ
equ
equ
equ
equ
12
13
14
14
15
16
32
33
;'Read-Only1-Flag;in Bit 7 an dieser;Position
;Extendnummer
;reserviert
;Extend-Gruppe
;Flag für 'File unver-jändert ?' (Bit 7)
jAnzahl der Records im; letzten Extend
jAnfang der Blockta-;belle
;Aktuelle Recordnummer;im Extend
;RRN bei direktem Zu-jgriff
Abstände zwischen den FCB-Parametern
0002 diff ex eg
0011 = diff rc er
equ
equ
2
17
;Abstand der ex-Posi-;tion zur eg-Position
;Abstand der rc-Posi-Jtion zur cr-Position
125
BDOS-Listing
; FBASE-Adresse
bdos:
; BDOS-Seriennummer:•/; Diese 6 Bytes werden vom CCP, mit der im CCP gespeicherten; Seriennummer verglichen.; Näheres ist unter 'compare_serial' (01F5) im CCP be-; schrieben.
serial
0000 00 defs 6,0
; BDOS-Einsprung für alle Programme.•*; In ?bdos ( - ?boot-f-0005h) steht ein Sprung an diese Stelle
bdos_entry:*
0006 C3 0011 jp bdosl ;Fehlertabelle über-;springen
; Adressentabelle für die vier möglichen Fehlermeldungen..i; Diese Tabelle wird von der allgemeinen Fehlerroutine; 'error entry1 (034A) benutzt.
err_loc_table:•
0009 0099
OOOB OOA5
OOOD OOAB
OOOF OOB1
defw ?err_bad_sector
defw ?err_select
defw ?err_disk__ro
defw ?err file ro
;Bad Sector
;Select
;R/O
•File R/O
126
BDOS-Listing
; Startroutine für alle BDOS-Funktionen
; I: C - Funktionsnummer im Bereich von 0 bis no_of_funcs-1; DE - Funktionsparameter; ( = ASCII-Zeichen für zeichenbezogene Funktionen); (- FCB-Adresse für filebezogene Funktionen)
bdosl:
0011 EB EX0012 22 0343 LD
0015 EB
00160017
001A001D
7B32 ODD6
21 000022 0345
EX
LDLD
LDLD
DE,HL ;Parameter nach HL(§entry_word),HL jParameter zwischen-
jspeichernDE,KL ;Vertauschung wieder
;zurücknehmen
A,E(§entry_byte) , A
HL,0(§exit value),HL
0020 39 ADD HL,SP
0021 22 030F LD
0024 31 0341 LD
(üuser stack),HL
SP,stack
0027 AF XOR A0028 32 ODEO LD (§fcb_disk_#),A
002B 32 ODDE LD (§file_func?),A
002E 21 OD74 LD HL,?bdos_exit
;LSB des Parameters;getrennt speichern
;HL - 0;Rückgabeparameter;auf 0 setzen
;HL - 0 + SP; - Stackadresse;Stackadresse zwi-;schenspeichern
;Stackpointer auf;BDOS-Stack zeigen;lassen
A = 0Aktuelle Disk alsDisk für Fileopera-tionen annehmen(siehe 'auto_select'und '?bdos_exit')Erst einmal annehmen,daß es sich bei dergewünschten Funktionnicht um eine File-funktion handelt,(siehe auto select)
0031 E5 PUSH HL
JRückkehradresse fürjalle BDOS-Funktionen;auf den Stack legen
127
BDOS-Listing
0032 790033 FE 29
003F00400041
0042
0045
LDCP
0035 DO RET
0036 4B LD
5E2356
LDINCLD
2A 0343 LD
EB EX
0046 E9 JP
A,Cno of funcs
NC
C,E
;A - Funktionsnummer•rlst die Funktionsnum-;mer größer oder;gleich der Anzahl der;Funktionen ?;J: Die Funktionsnum-;mer ist zu groß,;keine Funktion aus-;führen
;N: C - LSB der Ein-jgangsparameters; (f ür zeichenbezogene;Funktionen)
0037003A003B003D003E
215F161919
0047
00
LDLDLDADDADD
HL,bdE, AD,0HL, DEHL, DE
HL,bdos_loc_table ;HL -> Adressentabelle
E,(HL)HLD,(HL)
HL,(§entry_word)
DE, HL
(HL)
;DE Funktionsnummer
;Funktionsnummer zwei-;mal aufaddieren;HL -> Adresse der ge-;wünschten Funktion;Funktionsadresse nach;DE laden
;HL - Eingangspara-;meter;DE und HL vertauschen;DE = Eingangspara-;meter;HL = Adresse der ge-jwünschten Funktion^Funktion ausführen
128
BDOS-Listing
r; Adresstabel; ihrer Funke
; Die mit ' b_; Sprunglei st; Label.*
bdos__loc__tablr
le aller BDOS-Funktionen in der Reihenfolgej onsnummern
' beginnenden Adress-Label weisen auf die BIOS-e. '?' am Labelanfang kennzeichnet ein BDOS-
e :
; Funktionsnummer00470049OC4B004D004F00510053005500570059005B005D005F00610063006500670069006B006D006F00710073007500770079007B007D007F00810083008500870089008B008D008F0091009300950097
OE0302C801 9002CEOE12OEOF02D402ED02F302F801E102FEOC7EOC83OC45OC9COCA5OCAßOCC8OCD7OCEOOCE6OCEC - 'OCF5OCFEOD04ODOAOD1 1052COD17OD1DOD26OD2DOD41OD47OD4DOCOEOD5303040304OD93
defwdefwdefwdefv/defwdefv/defwdefv/defwdefwdefv/defwdefv/defwdefv/defwdefwdefwdefwdefv/defv/defwdefwdefwdefwdefwdefwdefv/defwdefwdefv/defv/defwdefwdefv/defwdefwdefwdefwdefwdefw
b wboot?console input?console outputPreader inputb punchb_list?direct io?get_io_byte?set__io_byte?print_string?read console buffer?get console statusPreturn version #Preset disk systemPselect disk?open_f ile?close file?search_f irstPsearch next?delete_f ile?read sequPwrite sequ?make file?rename file?return login vec?return disk?set_dma?get_allocation addr?write_protect disk?get ro vec?set_f ile_attr?get_parameter_addr?set get user code?read random?write random?compute file size?set random record?reset disk?dummy?dummy?write zero random
•/•f»/*/•f•t•r•/•r•i•t
•t•t•/•/•/•
/•lm
i•t•r•l•l•/•f•/•
r•
/•
/•i•/•f•/»
/•
r•/•/•;*/•/
0123456789
101 11213141516171 819202122232425262728293031323334353637383940
129
3DOS-Listing
3DOS Fehlerroutinen
Fehlerart: Schreib/Lesefehler
Ursache: Die BIOS-Funktionen zum Lesen bzw. Schreibeneines Records haben einen Fehler gemeldet.
?err bad sector:
0099009C
21 OOCACD OOE5
OOA4 C9
LDCALL
009F FE 03 CPOOA1 CA 0000 JP
RET
HL,txt_bad_sectorshow error
ctrlcZ,?boot
;HL -> FehlertextFehlermeldung aus-geben und auf ein;Zeichen von derjConsole (Tastendruck)jwartenJCTRL-C gedrückt ?;J: Funktion abbrechen;und Warmstart aus-;führen;N: Funktion wieder-;holen
Fehlerart
Ursache:
?err select:
OOA5OOA8
21 OOD5C3 OOB4
Fehlerhafte Diskanwahl
Die BIOS-Funktion b_seldsk hat als DPH-Adresseden Wert OOOOH zurückgegeben.
LD HL,txt_selectJP err boot
;HL -> FehlertextFehlermeldung aus-;geben und WarmstartJausführen
Fehlerart: Disk schreibgeschützt
Ursache:
?errdiskro:
Das entsprechende Bit im R/0-Vektor ist gesetzt(Über STAT oder wegen einer PrüfSummen-Differenz )
OOAB 21 OOE1 LD HL,txt_disk_roOOAE C3 OOB4 JP err boot
;HL -> Fehlertext^Fehlermeldung aus-;geben und Warmstart;ausfUhren
1 30
BDOS-Listing
r
; Fehlerart: File schreibgeschützt
• Ursache:
?err file ro:
Das 'Read-Only ' -Bit im Directory-Eintrag istgesetzt.
OOB1 21 OODC LD HL,txt_f ile_ro ;HL -> Fehlertext
; UPRO für Fehlerroutinen.; Fehlertext anzeigen und Warmstart ausführen.•
; I: HL -> Fehlertext
errboot :
OOB4 CD OOE5 CALL showerror
OOB7 C3 0000 JP•r
?boot
Fehlermeldung aus-;geben und auf ein; Zeichen von derjConsole (Tastendruck);warten;Warmstart ausführen
; Texte für die verschiedenen Fehlermeldungen../; Dieser Text wird bei jeder Fehlermeldung ausgegeben:
errortext:
OOBA defm 'Bdos Err On '
; Hier v/ird die Bezeichnung der aktuellen Disk ein; getragen ( 'A1 - 'P1 )
§disknamel
OOC6 defm
1 3 1
BDOS-Listing
Fehlertexte für die verschiedenen BDOS-Fehler
txtbadsector :
OOCA
txtselect :
OOD5
txtf ilero:
OODC
txt disk ro:
OOE1
defm 'Bad Sector^'
defm 'Select^1
defm 'File ' ;Nach 'File ' steht;kein '$', also wird;das folgende 'R/O*;noch mit ausgegeben i
defm
; UPRO für Fehlerroutinen.; Komplette Fehlermeldung ausgeben und auf ein Zeichen von; der Console (Tastendruck) warten
; l: HL -> Fehlermeldung•rshow error:
OOE5 E5 PUSH HL
OOE6 CD 01C9 CALL print_cr_lf
OOE9 3A 0342 LD A,(§bdos_disk)OOEC C6 41 ADD A,'A1
OOEE 32 OOC6 LD (§disk_name),A
OOF1 01 OOBA LD BC,error_textOOF4 CD 01D3 CALL print_text
OOF7 C1 POP BC
OOF8 CD 01D3 CALL print_text
;Textzeiger retten
;Neue Zeile beginnen
JDisknummer holen; + 'A' ergibt die Disk;bezeichnung;Diskbezeichnung in;die FehlermeldungJeinsetzen
;BC -> FehlermeldungJErsten Teil der Feh-Jlermeldung ausgeben
;Textzeiger vom Stack;holen;und Fehlertext aus-;geben
132
i
BDOS-Listing
Zeichen von der Console holen
l: -
; O: A - Zeichen•tget_char:
OOFB 21 030E LD
OOFEOOFF01 01
01 02
01 03
7E36 00
CO
C3 OE09
LDLDOR
RET
JP
HL,§buffered_char ;HL -> Zeichen von;letzter Statusabfrage
A,(HL) ;A - Zeichen(HL),0 ;Zeichen löschenA ;War noch ein Zeichen
;zwischengepuffert ?NZ ;J: Dieses Zeichen zu-
;rückgebenb_conin ;N: Neues Zeichen von
;der Console holeni•ri•r
Zeichen von der Console holen und ausgeben
l: -
O: A - Zeichen
input_char:•
0106 CD OOFB01 09 CD 0114
01OC D8
01 ÖD010E010F01 1 201 1 3
F54FCDF1C9
01 90
CALL get__charCALL check_char
RET C
PUSH AFLD C,ACALL ?console_outputPOP AFRET
;Zeichen holen;lst es ein darstell;bares Zeichen ?;N: Zeichen nichtjausgeben;J: Zeichen retten;C = Zeichen;Zeichen ausgeben;Zeichen zurück;Fertig
1 33
BDOS-Listing
/•t•I
fmf
Zeichen überprüfen
0
A
AZC
ASCII-Zeichen
unverändert- 1, falls A- 1
'er1 , 'If, 'tab' oder 'back1
falls A der ASCII-Wert ein anderen, nicht dar-stellbaren Zeichens istC - 0 sonst
check char:
011401 1601 1 701 1 901 1 A01 1C01 1D01 1F01200122
•rr
FEC8FEC8FEC8FEC8FEC9
ÖD
OA
09
08
20
CPRETCPRETCPRETCPRETCPRET
erZIfZtabZbackZspace
A - er ?JAJAJAJ:
okIf ?
oktab
okbackok
A < ' space ' ?Zurück, mit ent-sprechend gesetztenFlags
Console auf anstehendes Zeichenholen.Falls das Zeichen CTRL-S (xoff)Zeichen gewartet.
überprüfen und Zeichen
war, wird auf ein zweites
; Diese Routine ist die 'Get Console Status'-Funktion des BDOS
char_xoff?:»
0123 3A 030E LD0126 B7 OR
0127 C2 0145 JP
A,(§buffered_char);Ist noch ein zwi-A ;schengepuffertes
;Zeichen vorhandenNZ,true_status ;J: Status 'true1
;melden
012A CD OE06 CALL b const
012D E6 01 AND012F C8 RET
r-u
;N: ConsolenstatusOS holenein ZeJchen
Status 'false'
;vom BIOS; Steht;N:; (Null ) melden
an:
134
BDOS-Listing
01 30013301 35
CD OE09FE 1 3C2 0142
CALL b__coninCP xoffJP NZ,save status
0138 CD OE09 CALL b conin
013B FE 03
0140 AF0141 C9
CP
01 3D CA 0000 JP
XORRET
ctrlc
Z,?boot
A
;J: Zeichen abholen;lst es CTRL-S ?;N: Zeichen zwischen-jpuffern und Status; ' true' melden
;J: Auf zweites Zei-;chen warten. Die;Verarbeitung ist so;lange gestoppt i;lst das nächste Zei-;chen CTRL-C ?;J: VJarmstart aus-;führen
;N: Status 'false'; zurückmelden
; Von der Console geholtes Zeichen zv/ischenpuffern und; Status 'true1 zurückmeiden•/save status:
0142 32 030E LD•i•t; Status 'true' zurückmelden
(§buffered char),A; Zeichen abspeichern
true_status:•
0145 3E 010147 C9
LDRET
;A = 'true' (<> 0)
; ASCiI-Zeichen ausgeben und Zeichenzähler aktualisieren•/; i: C = ASCII-Zeichen•T
; O: C unverändert
print__char:•
0148 3A 030A0149 B7
LDOR
014C C2 0162 JP
A, ( §dont_pr int? )A
NZ ,adjust__column
;Soll das Zeichen ausJgegeben werden ?;( siehe CTRL-H und re; type_line );N: Nur den Spalten-;zähler (§column) an-;passen
1 35
BDOS-Listing
014F C5 PUSH BC0150 CD 0123 CALL char xoff?
0153 C1
015401550158
015901 5A015D015E
C5CD OEOCC1
C53A 030DB7C4 OEOF
0161 C1
POP BC
PUSH BCCALL b_conoutPOP BC
PUSH BCLD A,(§list_flag)OR ACALL NZ,b list
POP BC
;N: Zeichen retten;CTRL-S abprüfen undVerarbeitung evtl.;anhalten;Zeichen zurück
;Zeichen retten;Zeichen ausgeben;Zeichen zurück
;Zeichen retten;§list_flag gesetzt ?
;J: Zeichen auch über;den List-Kanal aus-geben;Zeichen zurück
; Zähler für die Anzahl der in der aktuellen Zeile aus-; gegebenen Zeichen (§column) anpassen.tadjust column:
016201630166
0168
0169016A
7921FE
C8
34FE
030C7F
20
LDLDCP
RET
INCCP
A,CHL,§cdel
Z
(HL)space
016C DO
016D 35
016E016F0170
7EB7C8
RET
DEC
LDORRET
column
NC
(HL)
A,(HL)AZ
;A - Zeichen;HL -> Zähler;Ist das Zeichen; = 'del' ?;j; Fertig
N: Zähler +1Ist das Zeichendarstellbar ?(Also in der ASCII-Tabelle >= space ?}J: FertigN: Das zuletzt aus-gegebene Zeichen warein nicht darstell-bares ZeichenDie vorgenommene Er-höhung des Zählerswieder zurücknehmenA = ZählerIst der Zähler = 0 ?J: Fertig
136
BDOS-Listing
0171 79 LD0172 FE 08 rp
0174 C2 0179 JP
0177 35 DEC
A,Cback
NZ,not_back
(HL)
;N: A - Zeichen;War das Zeichen back-;space (Rückwärts-jschritt ?);N: Weitertesten
;J: Es wurde ein Zei-jchen gelöscht; Zäh-;ler entsprechend an-fassen
0178 C9 RET
not_back:•
0179 FE OA CP If
017B CO RET NZ
017C 36 00 LD (HL),0017E C9 RET
;Wurde eine neue Zeile;begonnen ?;N: Fertig
;J: Zähler auf Null;setzen
; ASCII-Zeichen in darstellbarer Form ausgeben
I: C - ASCII-Zeichen
O: -
•how char:
017F 79 LD A,C0180 CD 0114 CALL check_char
! »
0183 D2 0190 JP NC,?console_output
018601870189018C018D
F5OE 5ECD 0148F1F6 40
018F 4F
PUSHLDCALLPO?OR
LD
AFC ' " '^- rprint_charAF'§'
C,A
;A = Zeichen;ist es ein darstell;bares Zeichen ?;J: Zeichen ausgeben
;N: Zeichen retten; '"' (CTRL-Kennung);ausgeben;Zeichen zurück;ASCII-Wert zwischen;0 und 31 in ent-;sprechendes ASCII-Jzeichen '§' bis '_'^umwandelnJC = Zeichen für die;folgende Funktion
1 37
BDOS-Listing
**** BDOS-Funktion Nummer 2
I: C - Zeichen
0: -
"Console Output'
?console_output:
019001 910193
•i•t; Der; daß; wird•/
79FE 09C2 0148
Tab-Code
LDCPJP
wirddie nächste,*
A,CtabNZ ,print_char
vom BDOS in sovdurch 8 teilbare
;A - Zeichen; Zeichen - tab ?;N: Zeichen normaljausgeben
iel Leerzeichen gewandelt,Spaltenposition erreicht
show_tab:•i01960198019B019E
01AO
01A3
OE 20CD 01483A 030CE6 07
C2 Oi96
C9
LDCALLLDAND
JP
RET
C, spaceprint charA, ( ücolumn )7
NZ , show tab
;C - LeerzeichenjLeerzeichen ausgeben;A - Spaltenpositionjmodulo 8;Ist die Spaltenposi-jtion durch 8 teilbar?;N: Noch ein Leerzei-jchen ausgeben:J: Fertia
UPRO für ?read_console_buffer
Ein bereits ausgegebenes Zeichen, wird durch die Zeichen-sequenz 'backspace1 -Bildschirm gelösch
space' - 'backspace' wieder vom
print_backspace:
01A401A701A9
CDOECD
01 AC20OEOC
CALLLDCALL
print_backC,spaceb conout
;backspace ausgeben;spacejausgeben
; 'back'-Code ausgeben•tprint_back:
01 AC01 AE
OEC3
08 LD C,backOEOC JP b conout
;backspace; ausgeben
138
BDOS-Listing
; UPRO für ?read console buffer
; '#' ausgeben, neue Zeile anfangen und die Schreibposition; (Cursor) in die gleiche Spalte, wie beim Start von '?read_-; console_buffer' bringen.
new_line:•
01B1 OE 23 LD C,'#'01B3 CD 0148 CALL print_char01B6 CD 01C9 CALL print cr_lf
; ausgeben;Neue Zeile anfangen
; Solange Leerzeichen ausgeben, bis die Anfangs-Spalten-; position wieder erreicht ist.
new_line_loop:*
01B9 3A 030C LD
01BC 21 030B .LD
01 BF BE CP
0 i CO DO RET
01C101C3
1C6u
OE 20CD 0148C3 01B9
LDCALLJP
A, (§column)
HI., §start_pos
(HL)
MC
C,spacepr int__charnow line loop
;A - aktuelle Spalten-;position;HL --> Anfangs-Spal-; tenposition;Position vom Anfangjerreicht ?;J: Fertig
;N: Leerzeichen; ausgeben;ünd Position neu;testen
; Neue Ausgeibezeile beginnen
orint er
01C901CB01CE01 DO
OECDOEC3
ÖD01 48OA01 48
LDCALLLDJP
C,crprint_charC, Ifprint char
;Carriage Return; ausgeben;Line Feed; ausgeben
139
BDOS-Listing
• TI ext ausgeben.; Das Textende ist durch '$' gekennzeichnet.
; 0: EC -> '$' (Textende)•».'print text:
01D301D401D6
01D701D801D90 1 DA01DD01DS
OA— i — ir &C3
03C54FCDC1C3
24
01 90
01D3
LDCPRET
INCPUSHLDCALLPOPJP
A , { BC }i l iTZ
BCT~. *~1£>'^.
r A- / "?consoie ouBCprint text
tput
;Zeichen holen;Ende ( '$ ' ) errei;J: Fertig
:ht ?
;N: Zeiger +1;Zeiger retten;C - Zeichen;Zeichen ausgeben;Zeiger zurück;VJeiter, bis das Ende;erreicht ist
; **** BDOS-Fanktion Nummer 10 'Read Console Buffer'•r, I: ( §entry__wcrd ) -> Singabebuf f er•9
'f 0: Eingabebuffer, gefüllt mit den eirigegebenen Zeichen
?read console buffer:
OlE'i 3A C30C
01E4 o r, ~> n' - \j J LD
A, (§column)
( § s r.a r t_ po s ) , A
;Aktuelle Spaltenpcsi; t ion; in §start_pos merken
C1E7 2A 0343 LD01 EA 4 £ LD01KB 23 INC
01 EC E5'01 ED 06 00 LD
KL,(§entry_word) ;hL -> BufferC,fHL) ;C « BufferlänqeHL ;HL -> Buffer +1
PUSH HI,3,0
;Bufferadresse retten;B = Zähler der ein-;gegebenen Zeichen
; Bufferzeiger und Sufferzähler retten; Nächstes Zeichen voi. Console holen»r
read next.1 :
n, r C501 E? C01FO £5
PUSH 3CPUSH HL
1 40
BDOS-Listing
; Nächstes Zeichen von Console holen•/read_next2:•
01F1 CD OOFB CALL get_char
01F4 E6 7F AND 07FH
01F601F701F8
E1C1FE ÖD
POPPOPCP
HLBCer
01FA CA 02C1 JP Z,end_of_input
01 FD FE OA CP If
01FF CA 02C1 JP Z,end of input
0202 FE 080204 C2 0216
CP backJP NZ,check_del
^Zeichen holen (ohne;Ausgabe i);Bit 7 löschen
;Bufferzeiger zurück;Bufferzähier zurück;Eingabezeile be-;endet ?;J: Eingabe abschlies-; sen
;Eingabezeile be-;endet ?;J: Eingabe abschlies-; sen
;CTRL-H eingegeben ?;N: Sprung
; CTRL-H; Zuletzt eingegebenes Zeichen wieder löschen
0207 78
0208 B7
LD
OR
0209 CA 01EF JP
A,B
A
Z,read nextl
JA - Anzahl der be-Jreits eingegebenen; ZeichenJSchon Zeichen einge-; geben ?;N: CTRL-H hat am An-;fang einer Zeile kei; ne Funktion
020C 05 DEC
020D 3A 030C LD
0210 32 030A LD
0213 C3 0270 JP
B
A,(§column)
(§dont_print?),A
retype_line
J: Zeichenanzahl umeins verringernAktuelle Spaltenposi-tionfür back_char? spei-ehern und währendedes retype_loop keineZeichen ausgebenNeue Spaltenpositionbrechnen und ent-sprechend viele Zei-chen von der Consolelöschen
1 41
BDOS-Listing
check_del:•
0216 FE 7F0218 C2 0226
CP delJP NZ,check ctrle
;DEL eingegeben ?;N: Sprung
; DEL; Zuletzt eingegebenes Zeichen wieder
021B 78
021C B7
LD
OR
021D CA 01EF JP
0220 7E LD
0221 05 DEC0222 2B DEC0223 C3 02A9 JP
A,3
A
Z,read_next1
A, ( K L )
BHLshow input
löschen und ausgeben
;A - Anzahl der bisher;eingegebenen Zeichen;Stehen schon Zeichen;im Buffer ?;N: Dann kann auch;nichts gelöscht wer-;den
;J: Letztes Zeichen;holen;Zeichenzahler -1;Bufferzeiger -1;Zeichen ausgeben
check ctrle:
02260228
FE 05C2 0237
CP ctrleJP NZ,check_ctrlp
;CTRL-E eingegeben ?;N: Sprung
; CTRL-E; Neue Ausgabezeile beginnen, Buffer unverändert lassen
022B C5022C E5
PUSH BCPUSH HL
022D CD 01C9 CALL Drint er If
0230 AF XOR0231 32 030B LD
0234 C3 01F1 JP
A(§start_pos),A
read next2
Zeichenzählerund BufferzeigerrettenNeue AusgabezeilebeginnenA = 0Startposition aufNull setzenNächstes Zeichen ho-len .
142
BDOS-Listing
check__ctrlp:•
0237 FE 10 CP0239 C2 0248 JP
ctrlpNZ,check_ctrlx
;CTRL-P eingegeben ?;N: Sprung
; CTRL-P; Parallelausgabe der Consolenzeichenbzw. ausschalten.
023C023D02400242
E5213E96
030D01
PUSHLDLDSUB
0243 77
02440245
E1C3 01EF
LD
POPJP
HLHL,§print_flag
(HL)
(HL),A
HLread nextl
auf dem Drucker ein-
Bufferzeiger rettenHL -> §print_flagA - 1
falls §print_w a rfalls §printwar;print_f lag
A - 0,flag 1A - 1 ,flag 0NeuessetzenBufferzeiger zurückNächstes Zeichen ho-len
check__ctrlx:•0248 FE 18024A C2 025F
CP ctrlxJP NZ,check ctrlu
;CTRL-X eingegeben ?;N: Sprung
CTRL-XEingegebene Zeile löschen und Eingabe neu starten.Die bisher auf der Console angezeigten Zeichenwerden ebenfalls gelöscht.
024D E1 POP HL ;Bufferzeiger vom;Stack nehmen
1 43
BDOS-Listing
ctrlx_loop:
024E0251
3A 030B21 030C
0254 BE
LDLD
CP
0255 D2 01E1 JP
0258 35 DEC0259 CD 01A4 CALL
025C C3 024E JP
A,(§start_pos)EL r§column
(HL)
NC, ?read__console
(HL)print_backspace
ctrlx IOOD
;A - Startposition;HL -> aktuelle Spal-; tenposition;Startposition er-;reicht ?;J: Eingabe neu be-jginnen
buffer
;N: Spaltenposition -1;Zeichen auf der Con-;sole löschen;Weiter, bis Startpo-:sition erreicht ist
check ctrlu:
025F FE 15 CP0261 C2 026B JP
ctrluNZ,check ctrlr
JCTRL-U eingegeben ?;N: Sprung
; CTRL-U; Eingegebene Zeile löschen und Eingabe neu starten.; Die bisher auf der Console angezeigten Zeichen wer-; den nicht gelöscht, sondern eine neue Zeile begon-: nen.
02640267
CDE1
01B1 CALLPOP
newHL
line
0268 C3 01E1 JP
check ctrlr:
;Neue Zeile beginnen;Bufferzeiger vom; Stack nehmen und;Eingabe neu starten
?read console buffer
3
3
026B FE026D C2
1202A6
CP ctrlrJP NZ,save_char
;CTRL-R eingegeben ?;M: Sprung
144
BDOS-Listing
; CTRL-R; Ausgabezeile beenden und die bisher; neu anzeigen.r; UPRO für CTRL -K
eingegebene Zeile
; Neue Spaltenposition nach der Rücknahme des letzten; Zeichens berechnen.; beim ' retype_loop'; neu berechnet
retype_line :
0270 C5 PUSH0271 CD 01 B! CALL
0274 C1 -. --., POP0275 E1 POP
0276 E5 PUSH0277 C5 PUSHJ
; Bisher eingegebeneiretype_loop:
0278 78 L D0279 37 OR
027A CA 028A JP
027D 23 INC027E 4E l '' A" " LD027F 05 DEC0280 C5 PUSH0281 E5 PUSH0282 CD 01 7F CALL0285 E1 POP0286 C1 POP0287 C3 0278 JP
•
delete char:
028A E5 PUSH028B 3 A 030 A LD028E B7 OR028F CA 01 F1 JP
In diesem Fall,nicht angezeigt,
BCnew line
BCH L
HLBC
werden die Zeichensondern nur '§column'
; Zeichenzähler retten;Neue Ausgabezeile be;ginnen; Zeichen^ähler zurück;Buff erzeiger zurück
;Buff erzeiger retten;Zeichenzähler retten
Zeile neu anzeigen
A, BA
Z, delete char
HLC , ( HL )BBCHLshow charHLBCretype loop
HLA,(§dont print?)AZ , read_next2
;A = Zähler;Noch Zeichen auszu-; geben ?;N: weiter bei delete;char
;Zeiger +1;Zeichen holen;zähler -1; Zähler retten;Zeiger retten; Zeichen ausgeben;Zeiger zurück;Zähler zurück;Nächstes Zeichen aus;geben
;Buff erzeiger retten;Kam der Aufruf von;CTRL-H ?;N: Fertig, Nächstes;Zeichen holen
145
BDOS-Listing
0292
0295 96
030C LD
SUB
HL,Ucolumn
(HL)
;J: Alle Zeichen bis;zur neuen Spaüten-;pcsition zurücknehmen;A - Alte Spaltenpo-;sition;HL -> Neue Spalten-;position;A - Anzahl der noch;zu löschenden Zeichen
0296 32 030A LD (§back count),A ;Anzahl speichern
Zeichenlöschen
zwischen der alten und neuen Spaltenposition
back tab
0299029C0297
02AO02A3
CD2135
C2C3
01 A4030A
029901F1
CALLLDDEC
JPJP
print_backspaceHL,§back_count(HL)
NZ,back_tabread next2
; Zeichen löschen;HL -> Zähler;Zähler -1 , Noch;chen ZL löschen;J: Zeichen löschen;N: Fertig, Nächstes; Zeichen holen
Z e -
Das eingegebenes Zeichen v/a r kein Steuercode;Zeichen in den Buffer übernehmen und anzeigen.
save char:
02A6 2302A7 77
02A8 04
INCLD
INC
/eichen ausgeben
show input:
02A902AA02AB02 AC02AF0230
C5E54FCDElC1
01 7F
PUSHPUSHLDCALLPO?POP
HL(HL),A
3CHLC,Ashow_charHL
;Bufferzeiger +1;Zeichen in den Buf;fer übernehmen;Zeichenzähler +1
;Zeichenzähler retten;Bufferzeiger retten;C = Zeichen;Zeichen ausgeben;Bufferzeiger zurück;Zeichenzähler zurück
146
BDOS-Listing
02B1 7E LD
02B202B402B5
02B8
02BA
FE78C2
FE
CA
03
02BD
01
0000
CPLDJP
CP
JP
A,(HL)
ctrlcA, BNZ,not ctrlc
1
Z,?boot
;Zeichen aus dem Buf-;fer holen;War es CTRL-C ?;A = Zeichenzähler;N: Weiter
;J: War es das erste;Zeichen ?;J: Warmstart
not ctrlc:
02BD B9 CP
02BE DA 01EF JP C,read_next1
; Ende der Zeileneingabe
end of input:
02C1 E1
02C2 70
02C302C5
OE ODC3 0148
POP HL
LD (HL),B
LD C,erJP print_char
;N: Maximale Zeichen;zahl erreicht ?;N: Nächstes Zeichenjholen;J: Eingabe beenden
;Bufferanfangszeiger;zurück;Anzahl der eingegebe-;nen Zeichen abspei-;chern;C - CR-Code;Ausgabezeile ab-;schliessen
. **** BDOS-Funktion Nummer 1 'Console Input*
?console_input :•
02C8 CD 0106 CALL input_char
02CB C3 0301 JP return_byte
;Zeichen von der Con-Jsole holen;und zurückgeben
. **** BDOS-Funktion Nammer 3 'Reader Input1•i?reader_input:*
02CE CD OE15 CALL b_reader
02D1 C3 0301 JP return byte
JBIOS-Aufruf 'Reader;Input';Zeichen zurückgeben
1 47
BDOS-Listincr
; **** BDOS-Funktion Nummer 6 'Direct Console I/O'
?direct_io:»r02D4 79
02D5 3C
LD
INC
02D6 CA 02EO JP
02D9 3C IMC
02DA CA OE06 JP
02DD C3 OEOC JP
A,C
A
Z,direct_conin
A
Z,b_const
b conout
tr; UPRO für ?cirect_io; Console Eingabe«direct_conin:•
02EO CD OE06 CALL b_const02E3 B7 OR A02E4 CA OD91 JP Z,ret_to_user
02E7 CD OE09 CALL b_conin02EA C3 0301 JP return byte
;A - Eingangspara-;meter;Parameter = OFFH ?; (Console Input ?);J: Console Input
;Parameter - OFEH ?;(Console Status ?);J: BIOS-Aufruf 'Con-;sole Status*
;N: Parameter ist Zei-;chen; Zeichen ausge-;ben
;Steht ein Zeichen von;der Console an ?;N: Fertig
;j; Zeichen holenJund zurückgeben
; **** BDOS-Funktion Nummer 7 'Get I/O Byte'
?get io byte:
02ED02FO
3A 0003C3 0301
LDJP
A,(§io_byte)return_byte
; I/O-Byte holen;und zurückgeben
BDOS-Funktion Nummer 8 'Set I/O Byte1
?set_io_byte:•
02F3 21 0003 LD02F6 71 LD
02F7 C9 RETrn
HL,§io_byte(ML),C
JHL -> I/O-Byte;Neues I/O-Byte ein; setzen
1 48
BDOS-Listing
r
. **** BDOS-Funktion Nummer 9 'Print String1
?print_string:•
02F8 EB EX DE,HL ;HL - Textzeiger02F9 4D LD C,L02FA 44 LD B,H ;BC - Textzeiger02FB C3 01D3 JP print_text ;Text ausgeben•/•
; **** BDOS-Funktion Nummer 11 'Get Console Status'r?get_console_status:•
02FE CD 0123 CALL char_xoff? ;Consolenstatus holen;und zurückgeben:
r; Byte-V7ert an das aufrufende Programm zurückgeben•rreturn_byte:•t0301 32 0345 LD ( §exit_value ) , A ;Wert abspeichern•t•r. **** BDOS-Funktionen Nummer 38 und 39; Keine Funktion/?dummy :»
0304 C9 RET ;Rücksprung nach; ' ?bdos_exit '
; UPRO für Dateibezogene BDOS-Funktionen; Fehler bei Diskettenein-/ausgabe melden•tread_write_error :•
0305 3E 01 LD A , 1 Fehlercode 10307 C3 0301 JP return_byte ; zurückgeben
149
BDOS-Listing
; Parameterbereich für zeichenbezogene Funktionen
; Flag, ob während 'retype_line' Zeichen ausgegeben werden; sollen; - OOH, Zeichen ausgeben; (CTRL-R Funktion); <> OOH, Nur den Spaltenzähler (§column) berechnen; (CTRL-H Funktion)?
§dont_print: ^Gleiche Adresse wie;§back_count:
•9ml
; Zähler für die CTRL-H Funktioni030A 00 §back count: defb 0
; Spaltenposition beim Beginn von ?read_console_buffer•
030B 00 , ,„„. §start_pos: defb 0
; Aktuelle Spaltenposition
030C 00 §column: defb 0«t•i; Flag für 'print_char*; = OOH, falls das Zeichen nur auf der Console ausgegeben; werden soll; = 01 H, falls das Zeichen auch über den List-Kanal aus-; gegeben werden sollr; Die Umschaltung dieses Flags, geschieht über CTRL-P bei; der ' read__console_buf f er ' -Funktion*
030D 00 §pririt_f lag: defb 0
; 1 Zeichen Zwischenpuffer für Console Status/Input
030E 00 §bufferedchar: defb 0t•r; Zwischenspeicher für den Stackpointer des aufrufenden; Programms. Das BDOS benutzt eine eigenen Stackbereich.r030F 0000 §user stack: defw 0
150
BDOS-Listing
; BDOS-Interner Stackbereich•
031 1 00 . defs 48,0•tstack:
; Erster Parameterbereich für dateibezogene BDOS-Funktionen•i•/; Nummer des aktuellen Userbereichs*
0341 00 §user_#: defb 0»/•r; Aktuelle Disknumrner•
0342 00 §bdoscüsk: defb 0
; Zwischenspeicher für 16-Bit Eingabewert beim BDOS-Aufruf; (meist steht hier die Adresse eines FCB)*
0343 0000 §entry_word: defw 0•/•t; Zwischenspeicher für 8/16-Bit Rückgabeparameter vom; BDOS-Aufruf
0345 0000 §exit_value: defw 0t»; Select Error•rselect_error:
0347 21 OOOB LD HL,err_loc_table+2;HL -> Fehlertabelle
; Allgemeiner Einsprung rür Fehlermeldungen*r; I: HL -> Adresse der gewünschten Fehlerroutineterror_entry:*
034A 5E LD E,(HL) ;E = LSB der Adresse034B 23 INC HL034C 56 LD D,(HL) ;D = MSB der Adresse034D E3 EX DE,HL ;HL = Adresse der Feh-
Jlerroutine034E E9 JP (HL) ;Fehlerroutine aus-
;führen
1 51
BDOS-Listing
; Allgemeine Kopierroutine; C Bytes von (DE) nach (HL) kopieren
; I: C - Anzahl der zu kopierenden Bytesj DE -> Quellbereich
HL -> Zielbereich
move_de__hl•
034F OC INC C
move_loop
0350 ÖD
0351 C3
0352 1A0353 770354 130355 23
DEC
RET
LDLDINCINC
C
0356 C3 0350 JP
A,(DE)(HL),ADEHLmove loop
;Zähler +1, da der;Zähler zuerst ge-;testet wird
;Zähler -1;Zähler = 0 ?;J: Fertig
;N: Byte holen;Byte speichern;Quellzeiger +1;Zielzeiger +1;Nächstes Byte
; UPRO für ?select_disk; Disk anwählen uncl Parameter übernehmen•t', I: §bäosdisk = Nummer der anzuwählenden Disk
• O:
E,0_
= 1 , falls die Disk seit denr, letztenWarmstart schonmal angewählt wurde.
ag gesetzt, falls der BIOS-Aufruf fehlerhaft war
physical_select:
0359 3A 0342 LD A, (§bc;os disk)
035C 4P LD C,A035D CD OE1B CALL b seldsk
;A = Gewünschte Disk-;numner;C = Disknummer;BIOS-Äufruf
036003610362
7CB5C8
LDORRET
A, HLir?ü
;KL = 0 ?
;j; Disk kann nicht; selektiert werden
1 52
BDOS-Listing
03630364036503660367
036A036B036C
036F03700371
0374037503760377
037A037D037F
0382038503860389038B
5E23562322
232322
232322
2323EB22
21OECD
2AEB21OECD
ODB3
ODB5
ODB7
- -
ODDO
ODB908034F
ODBB
ODC1OF034F
LDINCLDINCLD
INCINCLD
INCINCLD
INCINCEXLD
LDLDCALL
LDEXL DLDCALL
E, (HL)HLD , ( HL )HL(?§last_entry) ,HL
HLHL( ?§track) ,HL
HLHL(?§trkrecord) ,HL
HLHLDE,HL(?§xltab) ,HL
KL,?§dirbufC,8move de hl
HL, (?§dpb)DE, HLHL,§dpbC,15move de hl
038E 2A ODC6 LD
0391
0392
7C
21 ODDD
LD
LD
0395
0397
0398
039B
36 FF
B7
LD
OR
CA 039D JP
36 00 LD
HL,(§dsm)
A, H
HL,§large_dsm?
(HL),OFFH
A
Z , select__new__ok
(HL),0
;N: HL -> DPH;XLTAB-Adresse holen
jAdresse von DPH+2;merken
;Adresse von DPH+4jmerken
;Adresse von DPH+6jmerken
;HL - XLTAB-Adresse;XLTAB-Adresse;speichern
;Nach ?§dirbuf werden;die nächsten 8 Bytes;des DPH kopiert
;HL - DPB-Adresse;DE -> DPB;Nach §dpb werden die;15 Bytes des DPBJkopiert
HL = Anzahl derBlöcke der selek-tierten DiskA - MSB der Block-anzahlHL -> Flag, ob dieBlocknummern als 8-oder 16-Bit Werteverwaltet v/erdenErsteinmal 8-BitBlocknunmern annehmenIst das MSB derBlockanzahl = 0 ?J: Die Annahme warrichtigN: Die Blocknummernsind 16-Bit Werte
153
BDOS-Listing
select new ok
039D 3E FF LD039F B7 OR03AO C9 RETi
; UPRO für logical_
A, OFFHA
select und search fi; Spurnummer der angewählten Disk und d; DPH-Parameter aufthome disk:r03A1 CD OE18 CALL
03A4 AF XOR03A5 2A ODB5 LD03A8 77 LD03A9 23 INC03AA 77 LD
03AB 2A ODB7 LD03AE 77 LD03AF 23 INC03BO 77 LD03B1 C9 RET
Null setzen.
b_home
AHL, (?§track)(HL), AHL(HL),A
HL, (?§trkrecord)(HL) ,AHL(HL), A
;A ungleich Null;Z-Flag löschenjFertig
rstie dazugehörigen
;BIOS-Aufruf Track 0janwählen;A - 0;HL -> Spurnummer; Spurnummer auf; Null; setzen;HL -> Recordnummer;der Spur
;Spurrecord auf Null; setzen
; Record lesen und Fehlerbehandlung durchführen
read_record:*
03B2 CD OE27 CALL b_read0335 C3 03BB JP test rw status
;BIOS-Aufruf;Fehler ?
; Record schreiben und Fehlerbehandlung durchführen
v/rite_record :•
03B8 CD OE2A CALL bwrite
testrwstatus :
03BB B7 OR
03BC C8 RET
;BIOS-Aufruf
;Fehler beim BIOS;Aufruf ?;N: Fertig
154
BDOS-Listing
; Fehler: 'Bad Sector1 melden
bad sector error:
03BD 21 0009 LD
03CO C3 034A JP
HL,err_loc_table
error_entry
;J: HL -> Fehler-Adresse 'BAD SECTOR1
;Fehlerroutine aus-;führen
; Spur und Sektor im Directorybereich der Diskette anwählen•r; I: (§dir_eritry_#) - Nummer des gewünschten Directory-; Eintrags
set dir trk sec:
03C3 2A ODEA LD
03C6 OE 02 LD03C8 CD 04EA CALL shift_right_hl
03CB 22 ODE5 LD (§abs_rec_#),HL
03CE 22 ODEC LD
HL,(§dir_entry_#) ;HL - Nummer des Ein-;trags
C,002H ;C - 2;HL - HL/4 - Nummer;des gewünschten Di-;rectory-Records^Absolute Recordnummer;setzen
( §dir_record__#) , HL; Direcory-Recordnummer;speichern
; Spur und Sektor im Datenbereich der Diskette anwählen•t; I: (§abs_rec__#) = Nummer des gewünschten Records
set dsk trk sec:
03D103D403D5 2303D6 46
21 ODE5 LD HL,§abs_rec_/4E LD C,(HL)
INC HLLD B,(HL)
03D703DA 5E03DB 23
2A OD37 LDLDINC
03DC 56
HL,(?§trkrecord)E,(HL)HL
LD D,(HL)
;HL -> Recordnummer
;BC = Recordnummer
;DE = Nummer des ers-;ten Records der aktu-;ellen Spur
1 55
BDOS-Listinq
03DD 2A03EO 7E03E1 2303E2 6603S3 6F
7•t; Liegt; Spur ?
ODB5 LDLDINCLDLD
HL, (?§track)A, (HL)HLH,(HL)L,A
die gewünschte Recordnummer
;HL = Aktuelle Spur-jnummer
in einer niedrigeren
track dec:
03E4 7903E5 9303E6 7803E7 9A03E6 D2
03EB E503 EC 2 A
03EF 7B03FO 9503F1 5F03F2 7A03F3 9C03F4 5703F5 E103F6 2303F7 C3*
; Liegt; einerr
LDSUBLDSBC
03FA JP
PUSHODC1 LD
~ * ' LDSUBLDLDSBCLDPOPDEC
03£4 JP
A,C•nr1.
A, BA, DNC, track inc
HLHL, ( §spt )
A, ELE, AA, DA, HD, AHLHLtrack__dec
die gewünschte Recordnummerhöheren Spur ?
;Ist die Recordnummer; kleiner als der; Spurrecord ?
;N: Sprung
; Spurnummer retten;HL - Anzahl der Re-;cords pro Spur; Spurrecord der; nä'chstkleineren; Spur berechnen
•Spurnummer zurück; Spurnummer -1;Test wiederholen
in der aktuellen oder
track__inc:*
03FA E5 PUSH HL03FB 2A ODC1 LD HL,(§sptJ
03FE 19 ADD HL,DE
03FF DA 040F JP C,track found
; Spurnuinmer retten;HL = Anzahl der Re-;cords pro Spur;Spurrecord der nächs-;ten Spur berechnen.;Überlauf ?;J: Die höchstmögliche;Spur ist erreicht.;Die auf dem Stackfliegende Spurnummer;muß richtig sein.
156
BDOS-Listing
0402040304040405
040G
0409
040A040B040C•r•r
7995789C
DA 04 OF
EB
E123C3 03FA
LD A,CSUB LLD A, BSBC A, H
JP C, track_f ound
EX DE , HL
POP HLINC HLJP track_inc
;lst der Spurrecord; der nächsten Spur; größer als die ge-; wünschte Recordnum; mer ?;J: Die Recordnummer; liegt in der aktu-jellen Spur;N: DE - Spurrecord;der nächsten Spur; Spurnummer zurück;Spurnummer +1;Test wiederholen
•f Richtige Spurnummer erreicht*f
; BC; DE; HL•t
-= Gewünschte Recordnummer- Nummer des ersten Records der berechneten Spur- Spurnummer
trackfound:
040F E1
0410041 1041 2041 3041 4
0418041 9041 A
041E042104220423
C5D5-E5EB2A ODCE
041 7 19
444DCD
041D D1
OE1E
2A ODB5732372
POP HL
PUSH BCPUSH DEPUSH HLEX DE,HLLD HL,(§off)
ADD HL,DE
LD B, HLD C,LCALL b settrk
POP DE
LD HL,(?§track)LD (HL),EINC HLLD (HL),D
;Spurnummer vom StackjholenjRecornummer retten;Spurrecord retten;Spurnummer retten;DE = Spurnummer;HL = Anzahl der re-;servierten Spuren;Physikalische Spur-;nummer berechnen
;BC = phys. Spurnummer;BIOS-Aufruf: 'Spur;setzen'
jSpurnummer vom Stack;holen;HL -> DPH + 2;Spurnummer im DPH; speichern
1 57
BDOS-Listing
0424 D1 POP DE
042504280429042A
042B
042C042D042E042F04300431043204350436
043904 3 A
043B
*t•
2A ODB7732372
C1
79934F789A472A ODDOEBCD OE30
4D44
C3 OE21
; Blockpositi•9
LDL DINCLD
POP
LDSUBLDLDSBCLDLDEXCALL
LDLD
JP
on in
HL, (?§trkrec(HL) ,EHL( HL ) , D
BC
A,CEC,AA, BA, DB, AHL, (?§xltab)DE , HLb sectrn
C,LB, H
b_setsec
der Blocktabel
;Neuen Spurrecord vom;Stack holen;HL -> DPI! + 4;Neuen Spurrecord im: DPH soeichern
jRecordnummer vom;Stack holen;BC - Recordnummer; minus Spurrecord; - Recordnummer; innerhalb der; berechneten Spur
;HL -> XLTAB;DE -> XLTAB;BIOS-Aufruf Sektor-;riummer aus der XLTAB;holen
;BC - PhysikalischejSektornumincr;BIOS-Aufruf: 'Sektor;setzen'
berechnen
get_block_pos:•
043E 21 ODC3 LD
0441 4E LD0442 3A ODE3 LD
HL,§bsh
C,(HL)A,(§sequ rec
;HL -> Block ShiftJFactor;c = BSH;A = Aktuelle Record-;nummer innerhalb des;aktuellen Extends
158
J
BDOS-Listing
; Relative Blocknummer des aktuellen; Extends) berechnen
; - Aktuelle Recordnummer / 2ÄBSH?block_loop__1 :r0445 B7 OR A0446 1F RRA0447 ÖD DEC C0448 C2 0445 JP NZ ,block_loop_1
044B 47 LD B, A
044C 3E 08 LD A, 8044E 96 SUB (HL)044F 4F LD C,A
0450 3A ODE2 LD A, ( §extend_#)
?r•r Relative Blocknummer des aktuellen
Records (innerhalb des
;CY-Flag löschen;A - A/2• p 1r ';Weiter, bis C - 0
;B - Relative Block-;nummer innerhalb des;aktuellen Extends
;C = 8 - BSH - Anzahl;der Blöcke pro Extend;A - Aktuelle Extend-jnummer
Extends berechnen; = Aktuelle Extendnummer * Anzahl der Blöcke pro Extend?block_loop_2 :
0453 ÖD DEC C0454 CA 045C JP Z,add_a_b
0457 B7 OR A0458 17 - RLA0459 C3 0453 JP block_loop_2r
;c -1 , C - 0 ?;J: Ende der zweiten;Schleife
;CY-Flag löschen;A = A * 2;Weiter, bis C = 0
add a b:
045C 80 ADD A, B
045D C9
Relative Blocknummerdes aktuellen Extendszur relativen Block-nummer des aktuellenRecords addierenDies ergibt die Num-mer des Blockes rela-tiv zum Eintrag unddamit die Positionder aktuellen Block-nummer in der Block-tabelle
RET
1 59
BDOS-Listing
t•r Aktuelle Blocknummer aus der Blocktabelle holen*/; I : BC = Position; tabelle•fget_block__#:«/045E 2A 0343 LD0461 11 0010 LD
0464 19 ADD0465 09 ADD0466 3 A ODDD LD0469 B7 OR
04 6 A CA 0471 JP
046D 6E LD046E 26 00 LD0470 C9 RET•* , t9; 1 6-Bit Wert aus»/get block word:•/0471 09 ADD
0472 5E LD0473 23 INC0474 56 LD0475 EB EX0476 C9 RET•/•t; Blocknummer des; in §block ft spei•/set ublock #:/
der Blocknummer innerhalb der Block-
HL , ( §entry_word )DE, pos_dx
HL, DEHL , BCA, ( §large dsm? )A
Z, get block word
L, (HL)H,0
;HL -> FCB;DE - Position der;Blocktabelle;HL -> Blocktabelle;HL -> Blocknummer;Werden die Block-jnumrnern als 1 6-Bit; Werte verwaltet ?;J: 1 6-Bit Wert holen
;N: L - Blocknummer; HL = Blocknummer
der Blocktabelle holen
HL , BC
E , ( HL )HLD , ( HL )DE, HL
aktuellen Records demehern
0477 CD 043E CALL get_block_pos
i
047A 4F LD047B 06 00 LD
C,AB,0
;Position nochmals;auf addieren, da jede;Blocknumrner zwei;Bytcs belegt;E = LSB der Block-; nummer;D = MSB;HL = Blocknummer
FCB entnehmen und
;Position der Block-jnummer innerhalb der;Blocktabelle berech-;nen;BC = Position
1i-i
160
BDOS-Listing
047D CD 045E CALL get_block_#
0480 22 ODES LD (§block0483 C9 RET
,HL
jBlocknummer aus der;Blocktabelle holenjund speichern
; Blocknummer überprüfen•; I: §block_/•/; O: Z-Flag gesetzt, falls §block__#•tcheck_§block_#:•0484 2A ODE5 LD HL,(§block_#)0487 7D LD A,L0488 B4 OR H0489 C9 RET
0
;HL - Blocknumrner
;Flags setzen
; Absolute Recordnummer des aktuellen Records berechnen•r; I: §block_#; §sequ_rec_#•r; O: §abs_rec__#•/set_§record#:*
048A 3A ODC3 LD
048D 2A ODE5 LD
A,(§bsh)
HL,(§block #)
JA = Block Shift Fac-J tor;HL = Blocknummer
; Absolute Recordnummer des Blockanfangs berechnen; - Blocknummer * 2"ßSH
blkrec_loop:•
0490 29 ADD0491 3D DEC0492 C2 0490 JP
0495 22 ODE7 LD
HL, HLANZ,blkrec loop
JHL = HL * 2;A -1;Weiter, bis A = 0
(Sblkrecord),HL jRecordnummer desJersten Records;speichern
61
BDOS-Listing
0498 3A ODC4 LD049B 4F LD
A,(§blm)C,A
049C 3A ODE3 LD A,(§sequ_rec_/)
049F A1
04AO B504A1 6F
AND
ORLD
04A2 22 ODE5 LD
LL, A
( §abs rec ,HL
04A5 C9
A - BLMC - BLM - Anzahl derRecords pro Block -1A - Aktuelle Record-Nummermodulo Anzahl von Re-cords pro Block- Relative Nummer desRecords im Block+ Absolute Nummer desersten Records imBlockergibt die absoluteNummer des aktuellenRecords
RET
; Zeiger auf die Extendnummer des FCB berechnen•/; I: §entry_word -> FCB•r
Öl HL -> Extend-Nurnmer
get_extend_pointer:
04A6 2A 0343 LD04A9 11 OOOC LD04AC 19 ADD04AD C9 RET
EL r ( §entry_v/ord ) ; HLDE,pos_ex ;DEH L , D E ; HL
-> FCB= Extend-Position-> Extend-Nummer
"r Adressen der höchsten und der aktuellen Recordnummer; bezogen auf den aktuellen Extend berechnen•/; I: §entry_word -> FCB•/; O: DE -> Höchste Recordnummer im Extend; HL -> Aktuelle Recordnummer im Extend•rget_rc_cr_pointer:•
04AE 2A 0343 LD HL,(§entry_wcrd) ;HL -> FCB04B1 11 OOOF LD
04B4 1904B5 EB
ADDEX
04B6 21 0011 LD04B9 19 ADD
04BA C9 RET
DE,pos_rc
HL, DEDE, HL
HL,diff_rc_crHL, DE
;DE = Position der^höchsten Recordnummer
;DE -> Höchste Record-Jnummer
;HL -> Aktuelle Re-;cordnummer
162
BDOS-Listing
; UPRO für OPEN, READ und WRITE7; Recordposition dem FCB entnehmen
; I: §entry_word -> FCBw
; O: §sequ_rec_#; §max_ext rec =; §extend_JP/get_record_#s:
Nummer des Records innerhalb des ExtendsHöchste Recordnummer des ExtendsNummer des ersten Extends im FCB
04BB CD 04AE CALL
04BE04BF04C2
04C304C4
7E32EB
7E32
ODE3
ODE1
LDLDEX
LDLD
04C7 CD 04A6 CALL
04CA 3A ODC5 LD04CD A6 AND04CE 32 ODE2 LD
04D1 C9 RET
get_rc_cr_pointer ;FCB-Zeiger auf aktu-;elle und höchste Re-;cordnummer berechnen
A,(HL) ;Aktuelle Recordnummer(§sequ_rec_#),A ;vom FCB holenDE,HL ;HL -> Höchste Record-
;nummerA,(HL) - ;Höchste Recordnummer(§max_ext_rec),A ;von FCB holen
get_extend_pointer;Adresse der Extend-;Nummer berechnen
A,(§exm) ;A - Extend Mask(HL) ;Nummer des ersten Ex-(§extend_#),A ;tends berechnen
; UPRO für READ und WRITE•r; Neue Recordposition im FCB speichern*rupdate_record__#s I
04D2 CD 04AE CALL
04D5 3A ODD5 LD04D8 FE 02 CP
A , ( §sequential? )2
04DA C2 04DE JP NZ ,update_sequ_/
04DD AF XOR
get_rc_cr_pointer ;FCB-Zeiger auf aktu-jelle und höchste Re-jcordnummer berechnen;A = Zugriffsflag;'Write Random with;Zero Fill1 ?;N: Zugriffsflag ist;Abstand zum nächsten;Record;N: Write Random zählt;die Recordnummer;nicht v/eiter
A
163
BDOS-Listing
r
update_sequ_#:r04DE
04DF
04E2
04E304E4
04E5
04E8
4F
3A ODE3
81
77EB
3A ODE1
77
04E9 C9
LD
LD
ADD
LDEX
LD
LD
RET
;C - Abstand zum;nächsten Record;A - zuletzt bearnbei-;tete Recordnummer;Nächste Recordnummer;berechnen;und im FCB speichern;HL -> bisher höchste;Recordnummer
A,(§max_ext_rec) ;A = Neue höchste;Recordnummer;Höchste Recordnummer; im FCB aktualisieren
C,A
A, ( §sequ_rec_#)
A,C
(HL),ADE,HL
(HL) ,A
9•
/
; HL um C Bits nach rechts schieben und von links: 0-Bits nachrücken:
; HL = HL /
; i: C - Anzahl der Schiebeoperationen; HL - Anfangswert
O: HL - Anfangswert um C Bits nach rechts geschoben
shift_right_hl:
04EA OC INC
shif t__right_loop!
;C +1, da C auch 0;sein darf und daher;der Zähler zuerst ge-;testet wird
04EB04EC
04ED04EE04EF04FO04F104F204F304F4
ÖDC8 - -
7CB71F677D1F6FC3 04EB
DSCRET
LDORRRALDLDRRALDJP
CZ
A, HA
H. .AA, L
L, Ashi
; Zähler -1 ,;j; Fertig
Zähler =
;N: A = MSB;CY-Flag loschen;flS3 rechts schiebenJMSB zurückschreiben;A = LSB;LSB schieben;LSB zurückschreiben
shif t_right_loop ;Weiter, bis Zähler =0
164
BDOS-Listing
; Prüfsumme des Directory-Buffers berechnen•i•f I: ?§dirbuf -> Directory-Buffer•i•r Öl Prüfsumme des Directory-Buffers
checksum_dirbuf:*
04F7 OE 80 LD04F9 2A ODB9 LD04FC AF XOR
checksum__loop:
86 ADD04FD
04FE 23 INC04FF ÖD DEC0500 C2 04FD JP0503 C9 RET
C,1 28HL,(?§dirbuf)A
;128 Bytes aufaddieren;HL -> Buffer;A - 0
A,(HL) ;Nächstes Byte auf-i*
№,ä; addieren
HL ;Bufferzeiger +1C ;Zähler -1NZ,checksum_loop ;Weiter, bis Zähler -0
; HL um C Bits nach links schieben und von rechts; 0-Bits nachrücken lassen:"i•r HL - HL * 2"C
/; l: C = Anzahl der SchiebeoperationenJ HL = Anfangswert•f; O: HL = Anfangswert um C Bits nach links geschoben*
shift left hl:
0504 OC INC
shift_left_loop:•/0505 ÖD0506 C80507 29
DECRETADD
0508 C3 0505 JP
;C -1-1 , da C auch NullJsein darf und daher;der Zähler zuerst ge-Jtestet wird
C JZähler -1, Zähler =0?Z ;J: FertigHL,HL ;N: HL um 1 Bit nach
; links schiebenshift_left_loop ;Weiter, bis Zähler =0
165
BDOS-Listing
; UPRO für ?select_disk und ?write_protect_disk; Vektor-Bit setzen, Die Bitnummer ist die Nummer der/••t•/•/
aktuellen Disk
BC Alter Vektor
O; HL - Neuer Vektor mit - entsprechend der Disknummer -gesetztem Bit
set disk vec:
050B050C
050F0510
0516051705180519051A051B051C051D
C53A 0342
4F21 0001
PUSH BCLD A,(§bdos_disk)
LD C,ALD HL,1
0513 CD 0504 CALL shift left hl
C179B56F78B467C9
POPLDORLDLDORLDRET
BCA,CLL,AA,BHH,A
;Alten Vektor retten;A - Aktuelle Disk-;nummer;C - Disknummer;HL - Vektor mit Bit 0;gesetzt;HL um C Bits nach;links schieben ergibt;eine Vektormaske mitjentsprechend gesetz-;tem Bit;Alten Vektor zurück; und Vektormaske; einkopieren
; UPRO für disk_ro?; Entsprechendes Bit aus dem R/O-Vektor holen
i: -
; o: A 1, falls die Disk schreibgeschützt ist0 sonst
get_ro_bit:•/051E 2A ODAD LD
052105240525
05280529052B
3A4FCD
7DE6C9
0342
04EA
01
LDLDCALL
LDANDRET
A,(C,Ashi
A, L1
HL,(§ro_vec)
A,(§bdos_disk)C,Ashift_right_hl
;HL = R/O-Vektor
;C = Disknummer;HL um C Bits nachjrechts schieben;A = LSB von HL;Bit 0 maskieren
-166
j
BDOS-Listing
. **** BDOS-Funktion Nummer 28 'Write Protect Disk1
»
?write_protect_disk:
HL,§ro_vecC,(HL)HLB,(HL)
;HL -> R/0-Vektor
;BC - R/O-Vektor
0532
0535
0538053B
053C
053D
054005410542
CD 050B
22 ODAD
2A ODC823 """
EB
2A ODB3
732372
CALL
LD
LDINC
EX
LD
LDIMCLD
set_disk_vec
( §ro_vec) ,HL
HL, (§drm)HL
DE , HL
HL, (?§last_entry)
(HL) ,EHL(KL),D
; Entsprechendes Bit; setzen;Neuen Vektor spei-; chern
;HL = Anzahl der mög-; lichen Directory-Ein-jträge +1;DE - HL
;HL -> Höchste belegte; Eintragsnummer^Höchste belegte Ein-; tragsnummer gleich; der höchsten mög-; liehen Eintragsnum-; mer setzen und damit; 'Directory voll'; vortäuschen.
0543 C9 RET
•tUPRO für WRITEDirectory-Eintrag auf Schreibschutz testen
entry_ro?:•
0544 CD 055E CALL get_entry_pointer ;HL -> Eintrag
; UPRO für WRITE; FCB auf Schreibschutz testen
fcb ro?:
0547 11 0009 LD
054A 19054B 7E054C 17
054D DO RET
DE,pos_ro
ADD HL,DELD A,(HL)RLA
NC
'rDE = Position des;R/0-Flags;HL -> R/0 Flag;Flag holen und;Bit nach CY schieben;CY (Bit) gesetzt ?;N: Fertig;J: Fehler melden
1 67
BDOS-Listing
; 'FILE R/O1 melden•/file_ro_error:f054E 21 OOOF LD HL,err_loc_table+6;HL -> Fehlertabelle0551 C3 034A JP error_entry ;Fehlerroutinc auf-
;rufen
; UPRO für MAKE, OPEN, CLOSE und DELETE; Disk auf Schreibschutz testen
disk_ro?:•r0554 CD 051 E CALL get__ro_bit
0557 C3 RET Z
;R/O Bit holen;Bit gesetzt ?;N: Fertig;J: Fehler melden
; Disk ist schreibgeschützt, 'R/O1 melden•/disk_ro_error:
0558 21 OOOD LD KL,err_loc_table+4;HL -> Fehlertabelle055B C3 034A J? error_entry ;Fehlerroutine auf-
;rufen
; Adresse des aktuellen Eintrags im DIRBUF berechnen
get__entry_po inter :
055E0561
2A ODB93A ODE9
HL = HL A
LDLD
KL,(?§dirbuf)A,(§dir_pos)
;HL -> DIRBUFJA = Position des;Eintragc im DIRBUF
a d d h l a
056405650566
05670568
856FDO
24C9
ADDLDRET
INCRET
A, LL, ANC
H
;LS3s addieren;LSB setzen;Fertig, falls kein;Übertrag;Übertrag in XSB über-;nehmen
1 68
BDOS-Listing
; Nummer (und Adresse) der Extendgruppe holen•
; I: §entry_word -> FCB•/; O: A - Extendgruppen-Nummer bzw. 'NA'-Flag; HL -> Extendgruppen-Nummer bzw. 'NA'-Flag
get_eg:•
0569 2A 0343 LD056C 11 OOOE LD
056F 190570 7E0571 C9
ADDLDRET
HL,(§entry_word) ;HL -> FCBDE,pos_eg
HL, DEA,(HL)
;DE - Position der Ex-; tendgruppennummer;HL -> Extendgruppe;Extendgruppe holen
; Extendgruppen-Nummer auf Null setzen
zero_eg:•i0572 CD 0569 CALL get_eg
0575 36 00 LD (HL),0
0577 C9 RETt•rUPRO für OPEN und MAKE
;Adresse der Extend-jgruppennummer holenyExtendgruppe auf Null;setzen
. ' (iM -,.*''(
; 'NA'-Flag setzen; Damit erhält der FCB die Kennung 'File unverändert'
not altered: <.•<•'•*•*'•
0578 CD 0569 CALL get_eg
057B F6 80 OR 080H057D 77 LD (HL),A057E C9 RET
;Adresse des Flags;holenJFlag setzen;und zurückschreiben
169
BDOS-Listing
Aktueller Eintrag frei ?
; I: §dir_entry_#
O: HL -> ?§last_entry + 1CY-Flag gelöscht, falls die Eintragsnummer größer als
die Nummer des höchsten belegten Eintrags ist.
entry•
057F05820583
05860587OS380589
058B
#_free?:
2A ODEA LDEB EX2A ODB3 LD
7B LD96 SUB23 INC7A LD9E SBCC9 RET
HL,(§dir_entry_#)DE, HLHL,(?§last_entry)
A,E(HL)HLA,DA,(HL)
;DE - Eintragsnummer;HL -> Nummer des;höchsten belegten;Eintrags +1;Eintragsnummer mit;der Nummer des;höchsten belegten;Eintrags verglei-;chen und CY-Flag;setzen
; Nummer des höchsten belegten Eintrags aktualisieren
new end of entries?:
058C CD 057F CALL entry_#_free?
058F D8
05900591059?0593OS94
13722B73C9
RET
INCLDDECLDRET
DE(HL),DHL(HL),E
;lst der aktuelle Ein-;trag neuer höchster;Eintrag ?;N: Fertig
;J: Eintragsnummer + 1;als neue höchste be-;belegte Eintragsnum-;mer + 1 speichern
170
BDOS-Listing
r; Differenz; HL - DE -rsub_de_hl:
0595 7B0596 950597 6F0598 7A0599 9C059A 67059B C9
zwischenHL
LDSUBLDLDSBCLDRET
DE '
A, ELL, AA, DA, HH, A
;LSBs subtrahieren
;MSBs subtrahieren
; CSV aktualisieren
update_csv:
059C OE FF LD C,OFFH ;C ist Flag für; 'aktualisieren'
; CSV testen oder aktualisieren*t• I: C - OFFH für CSV aktualisieren; C <> OFFH für CSV testenrtest_csv:
059E05A1
05A2
05A5
05A8
05A905AA05AD05BO05B1
05B4
05B505B605B7
2A ODBCEB
2A ODCC
CD 0595
DO
C5CD 04F72A ODBD
2A ODEC
19
C1OCCA 05C4
LDEX
LD
CALL
RET
PUSHCALLLDEXLD
ADD
POPTNCJP
HL, (§dir_DE , HL
HL, (§cks)
sub de hl
NC
BCchecksumHL, (?§csvDE, HLHL, (§dir_
HL, DE
BCCZ , update
record
dirbuf)
record
csv by
;DE = Directory-Re-;cordnummer;HL = Höchste zu prü-;fende Recordnummer;Soll die aktuellejRecordnummer noch geJprüft werden ?;N: Fertig
;Flag rettenJPrüfsumme berechnen
;DE -> csv;HL = Directory-Re-;cordnummer;HL -> Prüfsumme im;csvJFlag zurück;CSV aktualisieren?;J: Neue Prüfsumme;eintragen
1 71
BDOS-Listing
05BA BE CP (HL)
05BB C8 RET
G5BC CD 057F CALL entry_#_free?
;N: Neue Prüfsummejgleich dem Vektor-;eintrag ?;J: Ok, fertig
05BF DO RET
05CO CD 052C CALL05C3 C9 RET
;N: Ist der aktuelle^Eintrag im freien Be-;reich ?
NC ;J: Der aktuelle Ein-;trag wurde neu ange-;legt, Prüfsummendif-;ferenz ist in Ordnung;N: Disk vorsichtshal-;ber schreibschützen
?write orotect disk
•; CSV aktualisieren•/update_csv_by te:
05C4 77
05C5•
C9
LD
RET
(HL),A ;Neue Prüfsumme in den;CSV eintragen
; Directory-Record schreiben
dir write:
05C605C9
05CC05CE05D1
t"'
CD 059CCD 05EO
OE 01CD 03B8C3 05DA
CALLCALL
LDCALLJP
upaate__csv ;CSV aktualisierenset_drna_to_dirbuf ;DMA-Adresse des BIOS
;= DIR'BUF setzenJFlag für BIOS-Aufruf;Record schreiben;und BIOS-DMA-Adressejwieder auf den alten;V7ert setzen
C,1write_recordrestore dma
; Directory-Record lesen/dir_read:•/
05D4 CD 05EO CALL set_dma_to_dirbuf ; BIOS-Di'lA-Adresse;= DIRBÜF setzen
05D7 CD 03B2 CALL read record ;Record lesen
172
BDOS-Listing
; BIOS-DMA-Adresse auf BDOS-DMA-Adresse setzen
restore_dma:•
05DA 21 ODB1 LD
05DD C3 05E3 JP
HL,§dma_address
set dma to hi
;HL -> BDOS-DMA-jAdresse;BIOS-DMA-Adresse;- (HL) setzen
; BIOS-DMA-Adresse - DIRBUF setzen
setdmatodirbuf :
05EO 21 ODB9 LD HL,?§dirbuf ;HL -> DIRBUF-Adresse
•t BIOS-DMA-Adresse - (HL) setzen
set dma to hi:
05E305E405E505E6t/
4E2346C3 OE24
LDINCLDJP
C,(HL)HLB,(HL)b setdma
;BC - (HL);BIOS-Aufruf
; UPRO für 'Search for First1
; DIRBUF zum aktuellen DMA-Bereich kopieren
move dirbuf to dma:
05E905EC05ED05FO05F2
2A ODB9EB2A ODB1OE 80C3 034F
LDEXLDLDJP
HL,(?§dirbuf)DE, HL JDE -> DIRBUFHL,(§dma_address) ;HL -> DMA-BereichC,128 ;128 Bytesmove de hl ;von DE nach HL ko-
pieren
173
BDOS-Listing
; UPRO für Directory-Operationen
idir_entry_# - Startwert (OFFFFH) ?
; I: §dir entry
; O: A - 0, falls §dir_entry_# - OFFFFH; A < > 0 sonst
all_entries_compared? :
05F5 21 ODEA LD05F8 7E LD05F9 23 INC05FA BE CP05FB CO RET
05FC 3C05FD C9
INCRET
HL,§dir_entry_#A,(HL)HL(HL)N Z
A
;HL -> §dir_entry_#;A - LSB
;MSB - LSB ?;N: Fertig
;LSB - MSB - OFFH ?;J: Z-Flag gesetzt
; UPRO für Directory-Operationeni•r §dir_entry_# auf Startwert (OFFFFH) setzen
reset_entry_#:
05FE 21 FFFF LD HL,OFFFFH ;HL = OFFFFH0601 22 ODEA LD (§dir_entry_#),HL ;§dir_entry_# - HL0604 C9 RET
; UPRO für logical_select; Nächsten Directory Record prüfen•r• I: C = OOH, falls der Record geprüft werden soll; C = FFH, falls die Prüfsumme neu gebildet werden soll
check_dir_record:•
0605 2A ODC8 LD0608 EB EX
0609 2A ODEA LD
060C 23 INC060D 22 ODEA LD0610 CD 0595 CALL
HL,(§drm)DE,HL ;DE = Höchste Ein-
; tragsnummerHL,(§dir_entry_#) ;HL = aktuelle Ein-
;tragsnummerHL jEintragsnummer +1(§dir_entry__#) ,?IL ;Neue Nummer speichernsub_de_hl ;lst die neue Nummer
;größer als die;hochste Nummer ?
174
BDOS-Listing
0613 D2 0619 JP
0616 C3 05FE JP
NC,check_dir_pos
reset entry #
;N: §dir_pos und;Prüfsumme berechnen;J: Eintragsnummer aufjStartwert setzen
*; §dir_pos berechnen und bei Erreichen eines neuen; Directory-Records die neue Prüfsumme berechnen.
check_dir_pos:•
0619 3A ODEA LD A, (§dir_entry_#)
061C E6 03061E 06 05•tdir_pos__loop:
062006210622
062A062B
062E06310632
8705C2 0620
0625 32 ODE90628 B70629 CO
C5CD 03C3
CD 05D4C1C3 059E
AND 3LD B, 5
ADD A,ADEC BJP NZ,dir_pos_loop
LD (§dir_pos),AOR ARET NZ
PUSH BCCALL set_dir_trk_sec
CALL dir_readPOP BCJP test csv
;A - LSB der Eintrags-jnummer;A =• Nummer mod 4;Nun A * 2~5 berechnen
;A - A * 2;B -1;Weiter, bis B - 0
;§dir_pos speichern;A - 0 ?;N: Fertig
J: Es wurde ein neuerDirectory Record er-reichtFlag (C) rettenDirectory Track undSektor anwählenund Record lesenFlag zurückPrüfsumme testen bzw.neu berechnen
175
BDOS-Listing
; UPRO für WRITEr; Belegungsstatus der; Zurückgegeben wird das; aus dem Belegungsvektor
übergebenen Blocknummer feststellen.der Blocknummer entsprechende Bi(ALV).
t
• T -/ -1- •
r* O *
rJ
get a*f
063506360638
0639063A063B"063C063D063E063F
06410642064306440645064606470648
0649
064A064B064C064D064E
BC - :
A,0 =
-D
Iv bit
79E6 073C
5F5779OF "-OFOFE6 1F
4F788787878787B1
4F
78 "OFOFOFE6 1F
Blocknummer
= 0, falls der Block- 1 , falls der Block
noch frei istbelegt ist
Bitnummer (siehe change alv bit)
0650 47
LDANDINC
LDLDLDRRCARRCARRCAAND
LDLDADDADDADDADDADDOR
LD
LDRRCARRCARRCAAND
LD
A,C7A
E,AD,AA,C
01FH
C,AA, BA, AA, AA, AA, AA,AC
C,A
A, B
01FH
B,A
;A - LSB der Block-; nummer modulo 8; + 1 - Bitnummer im; Vektor-Byte;E = Bitnummer;D = Bitnummer;A - LSB der Block-; nummer geteilt: durch 8
Die höchsten 3 Bitslöschen, da geraderotiert (i) wurdeWert in C speichernA = MSB der Block-nummer * 32(Dadurch werden dieunteren 3 Bits desMSB nach 'oben1 ge-schoben )
Diese 3 Bits in CeinmaskierenC = LSB der Block-nummer / 8
;A = MSB der Block-; nummer / 8
JObere 3 Bits wieder;löschenJund B = MSB der;Blocknummer / 8; setzen
176
BDOS-Listing
0651 2A ODBF LD0654 09 ADD
0655 7E
get_alv_loop:
065606570658065B
071DC2 0656C9
LD
RLCADECJPRET
HL,(?§alv)HL,BC
A,(HL)
ENZ,get_alv_loop
;HL -> ALV-Vektor;+ Blocknummer / 8
;Byte aus dem ALV-;Vektor holen und; jetzt noch das der;Blocknummer ent-;sprechende Bit nach;A,0 bringen:
;A links rotieren;Bitzähler -1;Weiter, bis Zähler «0
; UPRO für WRITE
; Belegungsvektor (ALV) aktualisierenr; I: BC = Blocknummer, dessen Status geändert werden soll; E Neues Bit für den Belegungsvektor (OOH oder 01 H)
change_alv_bit:•/065C D5 PUSH DE065D CD 0635 CALL get_alv_bit
0660 E6 FE AND OFEK0662 C1 POP BC0663 B1 OR C
set_alv_loop
0664 OF RRCA
0665 15 DEC
0666 C2 0664 JP
0669 77
066A C9
LD
RET
D
NZ,set_alv_loop
(HL),A
JNeues Bit retten;Vektoreintrag holen
;Bit löschenJNeues Bit zurück;und einmaskieren
;Bit nach rechts;schieben;Bitzähler -1JAlte Bitposition;wieder erreicht ?;N: Weiter
;J: ALV-Eintrag zu-;rückschreiben
177
BDOS-Listing
für
; Blocktabelle des Directory-Eintrags auswerten und die; Belegungsvektor (ALV) aktualisieren.r; I: Eintrag im DIRBUF, §dir_pos entsprechend gesetzt; C - OOH, für Blocknummern freigeben (bei DELETE); C = 01 H, für Blocknummern als 'belegt1 markieren; (bei logical select)*; O: ALVrupdate
066B066E
06710672
0673
update
06750676
0677
06780679067C
067D
06800681068206830685
a
CD1 1
1 9C5
OE
a
D1ÖD
C8
D53AB7
CA
C5E54E06C3
entsprechend
Iv:
055E CALL0010 LD
ADDPUSH
1 1 LD
Iv loop:
POPDEC
RET
PUSHODDD LD
OR
0688 JP
PUSHPUSHLD
00 LD068E JP
aktualisiert
get_entry pointerDE,pos dx
HL , DEBC
C,17
DEC
Z
DEA, ( §large dsm? )A
Z , word__value
BCHLC, (HL)B,0test block #
;HL -> Eintrag;DE - Position der;Blocktabelle;HL -> Blocktabelle;Flag (C) retten
;C - Maximale Anzahl;von Blöcken in der;Blocktabelle +1
;Flag zurück nach E;Blockzähler -1;Zähler = 0 ?;J: Fertig
;N: Flag retten;Sind die Blocknummern;in der Blocktabelle;16-Bit Werte ?;J: 16-Bit Wert holen
;N: Blockzähler rettenJTabellenzeiger retten;8-Bit Blocknummer; holenJBlocknurnmer testen
178
BDOS-Listing
7° 16-Bit Blocknummer aus der Blocktabelle holen5word value:
is a1. *, • " -C*
0688 ÖD0689 C5068A 4E068B 23068C 46068D E5
J/; B] ocktabellen
test__block_#:
068E 79068F 300690 CA 069D
0693 2A ODC6
0696 7D0697 910698 7C0699 98069A D4 065C
r
DECPUSHLDINCLDPUSH
CBCC, (HL)HLB , ( HL )HL
;Blockzähler -1; Blockzähler retten;LSB der Blocknummer; holen;MSB der Blocknummer; holen und Tabellen-jzeiger retten
eintrag testen
LDORJP
.
LD
LDSUBLDSBCCALL
A,CBZ . no_block_alloc
HL, (§dsm)
A, LCA, HA, BNC, change alv bit
; Nächsten Blocktabelleneintrag bearbe?no block_alloc:
069D E1069E 23069F C106AO C3 0675
POPINCPOPJP
HLHLBCupdate alv loop
;Ist die Blocknummerjgleich Null ?;J: Der Tabellenein-;trag ist unbelegt
;N: HL - maximale; Blocknummer;Ist die Blocknummer;kleiner oder gleich;der maximalen BlockJnummer ?;J: ALV anpassen
i ten
jTabellenzeiger zurüjTabellenzeiger +1jBlockzähler zurück:Nächsten Tabellenei;trag bearbeiten
9
BDGS-Listing
; UP°O für ?select_disk•/; Belegungs- und Prüfsummenvektor (ALV und CSV) neu setzen
logical select:
06A3 2A ODC6 LD
06A6 OE 03 LD
HL,(§dsm)
C,3
;HL ilaximale Block-
U U.MCJ
06 AB06AC06AD06AE
\^LJ
23444D2A
\j --ti->t\
OD3F
\^i\Lj
INCLDLDLD
; Belegungsvektor
clr_
06B106B306B4063506B606B7
06BA06BD
06BE06C106C206C3
06C4
06C706CA06CC06CD
i-i iSllX-LU i-LV-jliL. HJ.
HLB, HC,LHL, ( ?§alv)
komplett löschen
/•/•r•/•rmf
alv_loop:
3623OB78B1C2
2AEB
2A732372
CD
2 A362336
00
06B1
ODCA
ODBF
03A1
OD3303
00
LDINCDECLDORJP
LDEX
LDL DINCL D
CAL
LDLDINCLD
( HL ) , 0HLBCA, BCNZ,clr alv loop
HLr (§alO all )DE , HL
HL, ( ?§alv)(IIL) ,EHL( HL ) , D
L hone disk
HL,(?§last entry)( KL) , 3HL(HL) ,0
F•f•//
*/
*r9
f
*
r9
t•/
•f
•r•/•/
•r•f•r
;nummer
;HL - Maximale Block-;nummer / 2^3
-= (DSM / 8) + 1Länge des ALV
;HL -> ALV
06CF CD 05FE CALL reset entry #
;Byte löschen;Zeiger +1;Zähler -1;Zähler - 0 ?
;N: Weiter
DE = Erste zwei Bytesdes neuen ALV(von der Directorybelegte Blöcke)HL -> ALVErstesundzweites Byte ein-tragenDPH-Parameterinitialisieren
^belegten Einlrags+1Jauf 3 setzen
;Eintragsnummer auf;Startv/ert setzen
180
BDOS-Listing
login_next_entry:
06D2 OE FF
06DE06EO
LD C,OFFH ;C - Flag für CSV; aktualisieren
06D4 CD 0605 CALL check_dir_record ^Nächsten Eintrag in;den CSV übernehmen;Alle Einträge über-jnommen ?
al l_entr ies_compared?Z ;J: Fertig
06D7 CD 05F5 CALL06DA C8 RET
06DB CD 055E CALL
3E E5BE
LDCP
06E1 CA 06D2 JP
06E4 3A 0341 LD06E7 BE CP
06E8 C2 06F6 JP
06EB 23 INC06EC 7E LD
06ED D6 24 SUB
06EF C2 06F6 JP
06F2 3D DEC06F3 32 0345 LD
entry_not_right:
06F6 OE 01 LD
06F8 CD 066B CALL
06FB CD 058C CALL06FE C3 06D2 JP
get_entry__pointer ;N: Adresse des gerade;übernommenen Eintrags;holen
A,OE5H(HL) ;lst der Eintrag be-
jlegt ?Z , login__next_entry ;N: Nächsten Eintrag
;holenA,(§user_#) ;J: Gehört der Eintrag(HL) ;zum aktuellen Userbe-
;reich ?NZ,entry_not_right;N: weiter
HL ;J: HL -> FilenameA,(HL) ;A - Erstes Zeichen
;des Filenamens'$' ;lst das erste Zeichen
;ein '$' ?NZ,entry_not_rightJN: weiter
A(§exit value),A
;J: A = OFFH;und A als Rückgabe-;parameter speichern;(siehe CCP, 'submit;flag')
C f1
update alv
;C - Flag für 'ALV-;setzen';ALV aktualisierenJllöchste belegte Ein-;tragsnummer bestimmen
nev;_end_of_entries?login_next_entry jNächsten Eintrag
;übernehmen
181
BDOS-Listinq
; UPRO für 'Delete', 'Penane1 und 'Set File Attr1
•/; Parameter zurückgeben
return found flag:
0701 3A ODD4 LD
0704 C3 0301 JP
A,(§file_found?) ;A - Flag von Open,job das File gefunden:wurde
return_tayte ;Flag als Byte-Wert; zurückgeben
W
• UPRO für 'Search for First' und 'Search for next1
r• Extendnumner überprüfen
; T: A - 'Gewünschte' Extendnummer (aus dem FCB); C = 'Gefundene' Extendnummer (aus dem Directory-Eintrag)•/; 0: Z-Flag gesetzt, falls der gewünschte Extend vom Eintrag; abgedeckt wird
check_extend_#:
0707 C50708 F5
070E 79070F AO0710 4F
071 1 F1
0712 AO0713 91
0714 E6 1F
07 l 6 C10717 C9
PUSH ECPUSH AF
0709 3A ODC5 LD070C 2F CPL070D 47 LD
LDANDL D
PO?
ANDSUB
AND
POPRET
A, (§exm)
B,A
A,CBC,A
3
01FH
BC
;Gefundene und; gewünschte Extend -jnurnmer retten;A = Extend Flask;ülaske negieren;B - Maske
JA = ExtendnummerjExtendnummer maskie-;ren und speichern
Gewünschte Extend-numrner zurückEbenfalls maskierenSind beide Extend-nummern im gleichenBereich ?Über/Unterlauf ver-nachlässigengefundene Extendnummer zurück
182
BDOS-Listing
•/; UPRO für 'Open' und 'Search for First1*t; Ersten passenden Directory-Eintrag suchen
; I: §entry_word -> FCBC = Anzahl der Bytes, in denen der Eintrag und der FCB
übereinstimmen müssen
; O: §file_found? = OOH, falls ein passender Eintrag gefundenwurde
- OFFII, sonst
jexit_value - Directory-Code (0 - 3), falls ein Eintraggefunden wurde
=- OFFH, sonst
search dir first
0718 3E FF071A 32 ODD4 LD
071 D 21 ODD8 LD
0720 71
LD A,OFFH ;Noch wurde kein pas-{§file_found?),A ;sender Eintrag gefun-
;denHL,§compare_count ;HL -> Vergleichs-
;zählerLD (IIL),C , ;Zähler vorbesetzen
0721 2A 0343 LD0724 22 ODD9 LD
HL,(§entry_word) ; HL -> FCB(?§search_fcb),HL ;FCB-Zeiger für
;'search_dir_next';speichern
0727 CD 05FE CALL reset_entry_# ;Eintragsnummer auf;Startwert setzen
072A CD 03A1 CALL home_disk ;DPH-Parameter initi-Jalisieren
; UPPxO für 'Open', 'Search for First1 und 'Search for Next'•i', Nächsten passenden Directory-Eintrag suchen•/; I; ?§search_fcb -> FCB (vom letzten 'search_dir_first'); §compare_count = Anzahl der zu überprüfenden Zeichen
search dir next:
072D OE 00 LD C,0 ;C = Flag für CSV;überprüfen
072F CD 0605 CALL check_dir_record ;Eintragsnummer erhö-;hen und CSV testenJLetzten Eintrag er-jreicht ?
0732 CD 05F5 CALL all_entries_compared?
183
BDOS-Listing
0735 CA 0794 JP
0738 2A ODD9 LD073B EB EX
073C 1A LD073D FE E5 CP073F CA 074A JP
0742 D5 PUSH0743 CD 057F CALL
0746 D1 POP0747 D2 0794 JP
search_rnake:
074A CD 055E CALL
074D 3A ODD8 LD0750 4F LD0751 06 00 LD
compare_next_loop
07530754
79B7
LDOR
0755 CA 0733 JP
0758 1A
0759 FE 3F
LD
CP
075B CA 077C JP
075E 78 LD
075F FE OD CP
0761 CA 077C JP
Z,entry_not_found ;J: Eintrag nicht ge-;funden
IIL, ( ?§search ccb)DE,HL
A,(DE)OE5IIZ,search make
;DE -> Zu suchender;FCB;A - Drivecode des FCB;Drivecode - -OE5H ?;J: Der Aufruf kam von;'Make File1, es soll;nur ein freier Ein-;trag gesucht werden.
DE ;FCB-Zeiger rettenentry_#_free? ;Folgen nur noch freie
;Einträge ?DE ;FCB-Zeiger zurückNC,entry_not_found;J: Eintrag nicht ge-
;funden
get_entry_pointer ;Adresse des aktuellen^Eintrags holen
A, { §cornpare_count )C,A ;C - Vergleichszähl erB,0 ;B = Position des
;nächsten zu verglei-;chenden Bytes
A,C ;A = ZählerA ;Alle Bytes ver-
;glichen ?Z, roir.urn_dir_code ;J: Eintrag gefunden
A,(DE) ;N: Nächstes Byte;aus deüi FCB holen
' ?' ;'Joker' ?;JI Byte nicht ver-;gleichen
Z , conipare_next_char
A,B ;N: A = aktuelle;Position
pos_s1 ;S1 erreicht ?;j: Byte nicht ver-;gleichen
Z,compare_next char
184
BDOS-Listing
0764 FE OC CP
0766 1A LD
0767 CA 0773 JP
pos_ex
A,(DE)
Z,compare_extend
;Extendnummer er-jreicht ?;A - Extendnummer aus;dem FCB;J: Extendnummern ver-jgleichen
076A 96
076B E6 7F
SUB
AMD
076D C2 072D JP
0770 C3 077C JP
•r
(HL) ;N: Stimmen die Bytesjuberein ?
07FH ;Bit 7 interessiert;nicht
NZ,search_dir_next;N: Nächsten Eintrag;überprüfen
compare_next__char ;J: Nächstes Zeichen;vergleichen
; Extendnummern vergleichen
compare_extend:•
0773 C50774 4E
PUSH BC ;Zähler rettenLD C,(HL) ;C » Extendnummer des
^Eintrags;Wird der gewünschte;Extend vom gefundenen;Eintrag abgedeckt ?
BC ;Zähler zurückNZ,search_dir_next;N: Nächsten Eintrag
;überprüfen;J: Nächstes Zeichen;vergleichen
0775 CD 0707 CALL check extend
0778 C1 POP0779 C2 072D JP
compare_next_char:
077C077D077E077F0780
1 32304ÖDC3 0753
INCINCINCDECJP
DEHLBCco
;FCB-Zeiger +1;Eintrag-Zeiger +1^Position +1;Zähler -1
ompare_next_loop ;Weiter, bis Zähler =0
; Eintrag gefunden•/; Directory-Code berechnen und zurückgeben
return_dir_code:•
0783 3A ODEA LD0786 E6 03 AND0788 32 0345 LD
A, ( §ctir_entry_#)03H(§exit value),A
;A = LSB der Eintrags-;nummer modulo 4;Dies ist der Direc-;tory-Code
1 85
BDOS-Listing
078B078E078F0790
07910792
217E17DO
ODD4
AF77
LDLDRLARET
0793 C9
XORLD
RET
HL,§fileA,(HL)
NC
A(HL),A
_found? ;HL -> Flag;A - Letzter Wert;Bit 7 - 1 ?;N: Es war nicht derjerste Versuch, es;wurde schon vorher;ein Eintrag gefunden;J: A = 0;Flag auf 'Eintrag;vorhanden1 setzen
; Keinen passenden Eintrag gefunden•rentry_not_found:•
0794 CD 05FE CALL reset__entry_#
0797 3E FF LD0799 C3 0301 JP
A,OFFHreturn byte
;Eintragsnummer aufjStartwert setzen;und Fehlercode OFFH; zurückgeben
; UPRO für 'Delete File'•i', Alle passenden Einträge löschen•/delete_files:*
079C CD 0554 CALL disk ro?
079F OE OC LD C,12
07A1 CD 0718 CALL search dir first
delete_loop:
07A4 CD 05F507A7 C8
;Disk schreibge-;schützt ?;JI 'R/O1 melden;N: Es müssen nur die;ersten 12 Zeichen;(Usernummer, Filename;und Filetype) über-Jeinstimmen;Ersten passenden Ein-;trag suchen
CALLRET
;Passenden Eintrag ge-;funden ?
all_entries_compared?Z ;N: Fertig
186
BDOS-Listing
07A8 CD 0544 CALL entry_ro?
07AB
;J: Eintrag schreibge-jschützt ?
CD 055E CALL yet__entry_pointer ;N: Zeiger auf den ge-jfundenen Eintrag;holen
07AE 36 E5 LD (HL),OE5H
07BO OE 00 LD C,007B2 CD 066B CALL update alv
07B5 CD 05C6 :ALL dir write
07B8 CD 072D CALL search dir next
07BB C3 07A4 JP delete loop
;Eintrag auf 'frei1
;setzen;C - 0;Alle vom Eintrag be-;legten Blöcke aus dem;ALV löschen;Eintrag auf Disk zu-;rückschreiben;Nachsten passenden;Eintrag suchen;und löschen
t»
; UPRO für ' V/rite1
; Nächstgelegenen freien Block suchen und belegen•r; I: BC - Nummer des zuletzt belegten Blocks•/; O: HL - 0, falls kein Block mehr frei ist; - Nummer des neu belegten Blocks sonst
allocate next block:
07BE 5007BF 59
LDL D
D,BE,C ;DE BC
; Im folgenden ist BC die Nummer des nächst-niedrigeren und; DE die Nummer des nächst-höheren Blocks, jeweils gemessen; zu der Nummer des zuletzt belegten Blocks.; Dadurch wird erreicht, daß ein File möglichst immer zusam-; menhängende Teile auf der Diskette belegt.
allocate_next_loop:
07CO 79 LD07C1 BO OR
07C2 CA 07D1 JP
07C5 OB DEC
A,C ;lst noch ein nied-B ;rigerer Block vor-
Jhanden ?Z,allocate_higher ;N: Höhere Blöcke
^überprüfenBC ;j: BC = Nummer des
;nachst-niedrigeren;Blocks
187
BDOS-Listing
07C607C7
07C807CB07CC
07CF07DO
/; Ist
D5C5
CD1FD2
C1D1
der
allocate/07D1
07D407D507D607D7
2A
7B957A9C
PUSHPUSH
0635 CALLRRA
07EC JP
POPPOP
DEBC
get alv bit
NC,allocate_block
BCDE
nächst-höhere Block frei ?
higher:
ODC6 LD
LDSUBLDSBC
HL, (§dsm)
A, ELA, DA, H
07D8 D2 07F4 JP
07DB 13
07DC07DD
07DE07DF07EO07E307E4
07E707E8
C5D5
424BCD 06351FD2 07EC
D1C1
INC
PUSHPUSH
LDLDCALLRRAJP
POPPOP
NC,allocate lower
DE
;Höhere und;niedrigere Blocknum-;mer retten;Bit aus dem ALV holen;Ist der Block frei ?;J: Block belegen
;N: Niedrigere und; höhere Blocknummer; zurück
;HL - Nummer desjhÖchsten Blocks;Nachst-höhere Block-Dummer mit der;höchsten BlocknummerDergleichen. Sind;noch höhere Blöcke;vorhanden ?;N: 'Oberes Ende1 der;Diskette erreicht:;'Untere' Blocke;testen
C7E9 C3 07CG JP
;J: DE - Nächst-;höhere Blocknummer
BC ;Niedrigere undDE ;höhere Blocknurnrner
;rettenB,D ;BC = Nummer des zuC,E ;testenden Blocksget_alv_bit ;ALV-Bit holen
Jlst der Block freiNC,allocate_block ;J: Block belegen
DE ;N: Höhere undBC Jniedrigere Block-
Jnummer zurückallocate_next_loop;und v/eitertesten
188
BDOS-Listing
; Gefundenen Block belegen•r; Die Blocknummer liegt zuoberst auf dem Stack*tallocate block:
07EC 17
07ED 3C
R L A
INCC07EE
07F1 E1
07F2 D1
:D 0664 CALL set_alv_loop
POP HL
POP DE
07F3 C9
;RRA vom Test zurück-;nehmen;Bit 0 setzen;und ALV-Eintrag zu-;rückschreiben;Blocknummer vom;Stack nehmen;zweite Blocknummer;ebenfalls vom Stack;nehmen
RET
W
", Es sind keine höheren Blöcke mehr frei
allocate_lower:•
07F4 79 LD07F5 BO OR
07F6 C2 07CO JP
07F9 21 0000 LD
07FC C9 RET
A,C ;Sind noch niedrigereB ;Blöcke vorhanden ?
;J: WeitertestenNZ,allocate_next_loop
HL,0 ;N: Es konnte kein;freier Block mehr;gefunden werden
; UPRO für 'Make File'•rr Kompletten Directory-Eintrag neu anlegen•f"r I: §entry_word -> FCB des neuen Eintrags
wri te_complete_entry:
07FD OE 00 LD C,0
07FF 1E 20 LD E,32
;FCB ab Position 0 in;den Eintrag überneh-;men;32 Bytes des FCB ab;der Startposition;übernehmen
1 89
BDOS-Listing
; UPRO für 'Rename File1 und 'Set File Attr'*t•t Directory-Eintrag teilweise neu anlegen•r; I: §entry_word -> FCB; C - Position, ab der der FCB in den Eintrag übernommen; werden sollj E - Anzahl der Bytes die übernommen werden sollen
write_partial_entry:•r0801 D50802 06 00
PUSH DELD B,0
;Anzahl retten;BC - Startposition
0804080708080809
2A 034309EBCD 055E
LD HL,(§entry_word) ;HL -> FCBADD HL,BCEX DE,HL ;DECALL get_entry_pointer ;HL
> Startposition> Eintrag
080C C1 POP BC080D CD 034F CALL move de hl
;C - Anzahl;C Bytes von DE nach;HL kopieren;und Directory Record;schreiben
; UPRO für 'Close1•r; Directory Record auf Disk schreiben
writedirrecord :
0810 CD 03C3 CALL set dir trk sec
0813 C3 05C6 JP dir writet9
t
; Fortsetzung von 'Rename File'
;Track und Sektor an-;wählen;und Record schreiben
rename file:
0816 CD 0554 CALL disk ro?
0819 OE OC LD C,12
081B CD 0718 CALL search dir first
;Disk schreibge-;schützt ?;Nur Usernurnmer, File-;namen und FiletypeDergleichen;Ersten Eintrag mit;altem Filenamen; suchen
1 90
BDOS-Listing
081E0821
0822
0825
0826
2A 03437E
11 001 0
19
77
LDLD
LD
ADD
LD
HL, (ientrA, ( H L )
DE,pos clx
HL,DE
( H L ) , A
HL -> FCBA - Usernummer desalten FilenamensDE - Position desneuen NamensHL -> Usernummer desneuen FilenamensDie alte Usernummerwird übernommen
rename__loop:•t
0827 CD 05F5 CALL082A Co ,. RET
082B CD 0544 CALL
082E OE 10 LD
0830 1E OC LD
0832 CD 0801 CALL
;Eintrag mit altem Na-;men gefunden ?
all_entries_compared?Z , . . , ;N: Fertig
entry_ro? ;J: Eintrag schreib-geschützt ?
C,16 ;N: C - Position des;neuen Filenamen und;Filetyps im FCB
E, 12 ;Nur Usernummer, File-jnamen und Filetype'. kopieren und^Eintrag auf Disk;schreiben
v/r i te_partial_entry
0835 CD 072D CALL search dir next
0838 C3 0827 JP rename loop
;Nächsten passenden;Eintrag suchen;und umbennen
; Fortsetzung von 'Set File Attr'
set file attr:
083B OE OC L D C 2 ;Nur die ersten 12;Zeichen (Usernummer,;Filename und Filetyp);vergleichen
083D CD 0718 CALL search dir first ;Ersten passenden Ein-
set_attr_loop:
0840 CD 05F50843 C8
Jtrag suchen
;Ersten/nächsten Ein-Jtrag gefunden ?
CALL aii_entries_corapared?RET ;N: Fertig
1 91
BDOS-Listing
0844
0846
0848
084B
084E
OE 00
1E OC
LD
LD
CD 0801 CALL
C,0 ;J: Vom FCB ab Posi-;tion 0
E,12 ;12 Bytes in den Ein-;trag übernehmen und;den Eintrag wieder; zurückschreiben
write_partial_entry
CD 072D CALL search dir next
C3 0840 JP s e t_a 11 r_l oop
;Nächsten passenden;Eintrag suchen;und neu setzen
f
; Fortsetzung von 'Open File1
_open_f ile:
OE OF0851 LD C,1 5 ;Die ersten 15 Bytes;(also auch die Ex-;tendnummer) verglei-;chen
search_dir_first ;Ersten passenden Ein-;trag suchen;Eintrag gefunden ?
0856 CD 05F5 CALL all_entries_compared?0859 C8 RET Z ;N: Fertig
0853 CD 0718 CALL
; Gefundenen Eintrag in den FCB übernehmen.•r*r Der gefundene Eintrag deckt entweder den gewünschten; Extend ab, oder der Extend liegt 'hinter' dem File-; ende.
open_entry:•
085A CD 04A6
085D 7E
085E085F0860
F5E5CD 055E
CALL get_extend_pointer;Adresse der Extend-;nummer des FCBs holen
LD A,(HL) ;A = Gewünschte Ex-;tendnummer
PUSH AF ;Extendnumrner rettenPUSH HL ;Zeiger rettenCALL get_entry_pointer ;Zeiger auf den Ein-
;trag holen
192
BDOS-Listing
0863 EB
086408670869
2 A 0343OE 20D5
EX DE,HL
LD Hu, ( §entry _wo:LD C,32PUSH DE
-H
086A CD 034F CALL move de hl
086D CD 0578 CALL not altered
0870 D1
0875 4E
087A 46
087B
087C
087D
E1
F1
77
087E 79
087F BE
0880 78
POP
0871 21 OOOC LD0874 19 ADD
LD
0876 21 OOOF LD0879 19 ADD
LD
POP
POP
LD
LD
CP
LD
0881 CA 088B JP
DE
HL,pos_exHL,DE
C,(HL)
HL t pos__rcHL , DE
B, (IIL)
HL
AF
(HL),Ä
A,C •'
(HL)
A,B
Z,set record
DE -> Gefundener Ein-tragHL -> FCB32 BytesZeiger auf EintragrettenKompletten Eintrag(32 Bytes) in denFCB kopieren'File unverändert1
markierenZeiger auf Eintragzurück
;HL -> Extendnummer;des Eintrags;C - Nummer des let:;ten Extends im gefun-;denen Eintrag
;HL --> Anzahl der Re;cords in diesem letz-;ten Extend;B - Anzahl der Re-;cords im letzten;Extend; Zeiger auf die FCB-;Extendnummer zurück^Gewünschte Extend-;nummer zurückJDie gewünschte Ex-;tendnummer wieder;in den FCB setzen;A = Höchste Extend-;nummer des Eintrags;lst die gewünschte;Extendnummer, die;Nummer des letzten;Extends ?;A = Anzahl der Re-Jcords im letzten;Extend
_count;J: Die Anzahl der Re-;cords im letzten Ex-;tend, ist die Anzahl;der Records im ge-;wunschten Extend
1 93
ßDOS-Listing
0884 3E 00 LD
0886 DA 088B JP
0889 3E 80 LD
A,0 -N: A 0;Liegt der gewünschtejExtend über dem letz-;ten Extend ?
C, set_record__count ; J: Der gewünschte Ex-;tend liegt 'hinter';dem Ende des FilesjDieser Extend enthält;also noch keine; (Null j ) Records
A, 128 ;N: Der gewünschte Ex-;tend liegt 'vor1 dem; letzten Extend des;Eintrags und wird;vom Eintrag komplett;abgedeckt.;Dieser Extend ist;also mit 128 Records;gef üllt.
; Anzahl der Records im geöffneten Extend, in den FCB; eintragen.
set record count:
088B088E08910892
2A1 11977
0343OOOF
LDLDADDLD
0893 C9 RET
HL,(§entry_word)DE,pos_rcHL, DE(HL),A
;HL -> FCB
;HL -> RecordnummerjRecordnummer ein-;setzen
; UPRO für 'Close File'•/; 16-Bit Blocknummer übernehmen
close word block:
08940895089608970898
7E23B62BCO
LDINCORDECRET
A, (HL)HL(HL)HLNZ
;ist der Blocktabel-; leneintrag frei ?
;N: Fertig
194
BDOS-Listing
0899 1A089A 77089B 13089C 23089D 1A089E 77089F 1B08AO 2B08A1 C9;/; Fortsetzungrclose file:
?08A2 AF08A3 32 034508A6 32 ODEA08A9 32 ODEB
08AC CD 051 E
08AF CO
08BO CD 056908B3 E6 80
08B5 CO
* , - A. •
08B6 OE OF08B8 CD 0718
08BB CD 05F508BE C8
08BF 01 0010
08C2 CD 055E
08C5 0908C6 EB
LD A, (DE)LD (HL),AINC DEINC HLLD A, (DE)LD ( HL ) , ADEC DEDEC HLRET
v
von 'Close File1
XOR ALD (iexit value), ALD (§dir entry #) ,ALD (§dir_entry_#+1 ) ,A
CALL get_ro_bit
RET N Z
CALL get egAND 080H
RET N Z
LD C,15CALL search dir first
;J: LSB; übernehmen
;MSB übernehmen
jRückgabeparameter auf;Null setzen;Eintragsnummer auf;Null setzen
;R/O-Bit der Disk; testen.;Disk schreibge-;schützt ?;J: Fertig, keinen;Fehler melden
; 'NA '-Flag holen;Wurde das File ge-;andert ?;N: Fertig, Ein un-;veränderter FCB wird;nicht in die Directo-;ry zurückgeschrieben
;J; Ersten passenden;Eintrag suchen;Eintrag gefunden ?
CALL all entries compared?RET Z
LD BC,pos_dx
CALL get entry pointer
ADD HL,BCEX DE , HL
;N: Fertig
;BC = Position der;Blocktabelle;Adresse des gefunde-;nen Eintrags holen
:DE -> Blocktabelle;des Eintrags
1 95
BDOS-Listing
08C7 2A 0343 LD08CA 09 ADD
08CB OE 10 LD
close__block__loop:•
08CD 3A ODDD LD08DO B7 OR08D1 CA 08E8 JP
HL,(§entry_wordHL,BC
C,16
;HL -> FCB;HL -> Blocktabelle;des FCBs;Alle 16 Einträge der;Blocktabelle über-jprüfen
A,(§large_dsm?) ;Sind die BlocknummernA ;1 6-Bit Werte ?Z,word_block_close;J: 16-Bit Blocknum-
;mern übernehmen
; Die Blocknummern sind 8-Bit Werte; DE -> Blocktabelle des Eintrags; HL -> Blocktabelle des FCB
byte_block_close:
08D4
08D5
08D6
7E
B7
1A
LD
OR
LD
A,
A
A,
(HL)
(DE)
08D7
08DA
C2 08DB JP
77 LD
close_byte_block:9
08DB
08DC08DF
B7
C2 08E17E
08EO 12
OR
JPLD
LD
;A - Blocknummer aus;dem FCB;Ist der Blocktabel-;leneintrag belegt ?;A - Blocknummer aus;dem Eintrag;J: Blocknummern tes;ten
NZ,close byte block
(HL),A ;N: Blocknummern^gleichsetzen
A JBlocknummer aus dem;Eintrag = 0 ?;N: Blocknummern ver-;gleichen
NZ, same_byte_block?A,(HL) ;J: Blocknummer von
;FCB(DE),A ;in den Eintrag über-
;nehmen
196
BDOS-Listing
same_byte_block?:
08E1 BE CP
08E2 C2 091F JP08E5 C3 08FD JP
(HL)
NZ,cant_closeclose next block
;Sind die beiden;Blocktabellenein-;träge identisch ?;N: Fehler;J: Nächsten Block-;tabelleneintrag über-;prüfen
; Die Blocknummern sind 16-Bit Werte•/; DE - > Blocktabelle des EintragsHL -> Blocktabelle des FCB
wordblockclose :
08E8 CD 0894 CALL close word block
08EB08EC08EF
EBCD 0894EB
EXCALLEX
08FO 1A
08F1 BE
08F2
LD
CP
C2 091F JP
08F5 1308F6 2308F7 1A
08F8 BE
INCINCLD
CP
08F9 C2 091F JP
08FC OD DEC•i
DE,HLclose_word_blockDE, HL
A,(DE)
(HL)
NZ, cant__close
DEHL ,A,(DE)
(HL)
NZ,cant_close
C
;Blocknummer vom Ein-;trag in den FCB über-;nehmen;Blocknummer vom FCB;in den Eintrag über-;nehmen
;A - LSB der Blocknum-;mer des Eintrags;gleich dem LSB der;Blocknummer des FCB ?;N: Fehler
;J: Beide Zeiger;erhöhen;A - MSB der Blocknum-;mer des Eintragsjgleich dem MSB der;Blocknummer des FCB ?;N: Fehler
;J: Blockzähler -1
; Nächsten Blocktabelleneintrag überprüfen
close next block:
08FD08FE08FF
1323ÖD
INCINCDEC
DEHLC
0900 C2 08CD JP
;Beide Zeiger;erhöhen;Blockzähler -1JWeiter, bis Block;zähler = 0
NZ,close_block_loop
197
BDOS-Listing
1
0903 01 FFEC LD BC,-20
0906 09
•t
ADD HL,BC
0907
0908
0909090A
EB
09
1ABE
EX
ADD
LDCP
DE,HL
HL,BC
A, (DE)(HL)
090B DA 0917 JP C,write_closed
090E 77 LD (HL),A
;Die 16 Positionen;Blocktabelle und;noch 4 weitere;Positionen abziehen
;DE -> Extendnummer;des FCB;HL -> Extendnummer;des Eintrags;Ist die Extendnummer;des FCB kleiner als;die Extendnummer des;Eintrags ?;J: Das File wurdejverkürzt. Neuen Entry;auf Disk schreiben
_entry
;N: Neue Extendnummer;in den Eintrag über-;nehmen
090F09120913
0914
09150916
01 000309EB
09
7E12
LDADDEX
ADD
LDLD
BC,3HL,BCDE,HL
HL,BC
A, ( H L )( D E ) , A
DE -> Höchste Record-nummer des letztenExtend im EintragHL -> Aktuelle Re-cordnummer im FCBRecordnummer des FCBals Recordnummer desEintrags übernehmenDadurch wird das Filean der 'aktuellenPosition1 geschlossen
Geschlossenen Eintrag auf Disk schreiben
write_closed_entry:•
0917* 3E FF LD0919 32 ODD2 LD
091C C3 0810 JP
A,OFFH JFlag für 'open_next(§entry_closed?),A;extend' setzen
write dir record ;Directory-Record;schreiben
198
BDOS-Listing
; Fehlerausgang, falls die Blocktabelleneinträge nicht mehr; stimmen
cant close:
091F 21 0345 LD
0922 35
0923 C9
DEC
RET
HL,§exit_value
(HL)
;HL -> Rückgabepara-jmeter (- 0 i);Parameter - OFFH;setzen
W
; Fortsetzung von 'flake File1
; UPRO für 'V/rite1 bei Fileerweiterungi; Neuen Directory-Eintrag erzeugen *' "J
t_make_file:
0924 CD 0554 CALL disk ro?
0927092A
092B092E
0931
0933
2A 0343 LD HL , ( §entry_word )E5 PUSH HL
;Disk schreibge-; schützt ?; HL -> FCB;FCB-Zeiger retten
21 ODAC22 0343
OE 01
CD 0718
LDLD
LD
0936 CD 05F5 CALL
0939093A093D
E122C8
0343POPLDRET
HL,§make_fcb ;HL -> OE5H(§entry_word),HL ;Adresse für 'search_
;dir_first' setzen~,1 ;Nur 1 Byte verglei-
JchenCALL search_dir_first ;Also einen Eintrag
;dessen erstes Byte;gleich OE5H ist
' ,,.,<•>. . . .--•;.!.,•.! ,-*,; ;(Dies ist die Ken-;nung für einen frei-;en Eintrag i ) suchenJWurde ein freier Ein-;trag gefunden ?
all_entries_compared?
HL ;FCB-Zeiger zurück( §entry_v/ord ) ,HL ;und wieder einsetzenZ ;N: Fertig
1 99
BDOS-Listing
093E EB093F0942
0943
21 OC19
OE 1 1
EX
ADD
LD
0945 AF XOR
make clear_loop:
0946 770947 230948 OD0949 C2 0946
LDINCDECJP
DE,HLHL, pos_rcHL,DE
C,17
(KL), AHLC
;DE -> FCB
;HL -> Recorclnummer;des FCB;Die nächsten 17 Bytes;(also die Recordnum-;mer und die Blockta-;belle);auf 0 setzen
;0 einsetzen; Zeiger +1jZähler -1
NZ ,make_clear_loop; Weiter , bis Zähler =0
i /-, -i iSI'-Position des neuen Eintrags auf Null setzen; und den Eintrag in die Directory zurückschreiben.
094C094F 190950 77
21 OOOD LDADD
— - - LD
HL,pos_s1HL, DE(HL),A -
0951
;HL -> S1- - ;S1 auf Null setzen
;Nummer des höchsten;belegten Eintrags;aktualisieren
CD 058C CALL new_end_of_entries?;FCB komplett in den;Eintrag übernehmen,;Eintrag auf Disk;schreiben
0954 CD 07FD CALL write_complete_entrynot_altered ;und File auf "unver-
;ändert* setzen0957 C3 0578 JP
; UPRO für 'Read1 und 'Write1
; Nächsten Extend des Files eröffnen, * i •_.{,open_next_extend:•/095A AF XOR A ;Ersteinmal annehmen,095B 32 ODD2 LD (§entry_closed?),A;daß kein neuer Ein-
;trag eröffnet werden;muß.
095E CD 08A2 CALL _close_file ;Aktuellen Extend;schliessen
200
BDOS-Listing
09610964
09650968096B
096C096D
CD 05F5C8
2A 034301 OOOC09
7E3C
096E E6 1F
0970 77
0974 47
097C A6
CALLRET
LDLDADD
LDINC
AND
LD
0971 CA 0983 JP
LD
0975 3A ODC5 LD0978 AO AND
0979 21 ODD2 LDAND
097D CA 098E JP
0980 C3 09AC JP
;Wurde der zu schlies-; sende Eintrag gefun-;den ?
a ll_entries_compared?Z ;N: Fehler
HL,(§entry_word)BC,pos_exHL,BC
A,(HL)A
01FH
(HL),A
Z tnext_ext_group
B, A
A,(§exm)B
HL,§entry_closed?(HL)
Z,search_extend
entry_found
HL -> Alte (geradegeschlossene) Extend-nummer des FCBA - ExtendnummerA - Nächste (zuöffnende) Extend-nummerA - Neue Extendnummermodulo 32Neue Extendnummerin den FCB eintragen.Ist die neue Extend-nummer ein Viel-faches von 32 ?J: Nächste Extend-gruppe eröffnen
;N: B - neue Extend-;nummer;A » Extend Mask;Neue Extendnummer;maskieren;A = 0, falls der;neue Extend in einem;neuen Eintrag liegt•EL -> Flag;A <> 0, falls der;neue Extend in dem;Eintrag liegt, der;gerade geschlossenjwurde. Ist dies der;Fall ?;N: EntsprechendenjEintrag suchen;j: Okf Eintrag ge-;funden
201
BDOS-Listing
T . .'
; Die neuen Extendnummer liegt in einer neuen Extendgruppe.; Neue Extendgruppe eröffnen
next_ext_group:•r098309860987
09880989098B
01 00020934
7EE6 OFCA 09B6
LDADDINC
LDANDJP
BC,diff_ex_egHL,BC(HL)
;HL -> Extendgruppe;Extendgruppen-;Nummer +1;A - Neue Extendgruppe;Extendgruppe > 15 ?
A,(HL)OFHZ,cant_extend_file;J: Maximale File-
;größe überschrit-; ten
; Eintrag des neuen Extends suchen
search extend
098E
0990
09930996
OE OF
CD 0718
LD
CALL
C,15 ;Extendnummer mit ver-jgleichen
search_dir_first jEintrag suchen;Wurde der Eintrag ge-funden ?
CD 05F5 CALL all_entries_compared?JP NZ ,entry_found ;J: okC2 09AC
; Für den neuen Extend konnte kein Eintrag gefunden werden
0999099C
3A ODD33C
LDINC
099D CA 09B6 JP
A, ( §read__or_write? )A ;Kam der Aufruf von
; 'Read1 ?Z , cant_extend_f ile; J: Fehler, Ende des
;Files erreicht
09AO CD 0924 CALL make file
09A3 CD 05F5 CALL
09A6 CA 09B6 JP09A9 C3 09AF JP
_ _ ; N : Eintrag f ü r d e n;neuen Extend anle-;gen.
. <. • .-. <,,..,. ,,: . ,_ ;Eintrag erfolgreichjengelegt ?
all_entries_compared?
Z ,cant_extend_f ile;N: Fehler meldennew_extend_opened ;J: Neuer Extend ist
;eröf f net
202
BDOS-Listing
; Es wurde ein passender Eintrag gefunden
entry_found:•09AC CD 085A CALL open_entry
; Es wurde ein neuer Extend geöffnet•/new_extend__opened:709AF CD 04BB CALL get_record_#s09B2 AF XOR A09B3 C3 0301 JP return_byte
;Eintrag mit ent-;sprechender Extend-;nummer eröffnen
;Parameter übernehmen;Keinen Fehler; zurückmelden
; Es konnte kein nächster Extend eröffnet v/erden
cant_extend_f ile :•/09B6 CD 0305 CALL read_write_error09B9 C3 0578 JP notaltered
;Fehler melden und;'File unverändert1
; setzen
Fortsetzung von 'Read Sequential1
read sequ:
•V t
09BC093E
3E 0132 ODD5
LDLD §sequential?) ,A
;Sequential-Flag;auf 1 setzen;(Die Recordnummer;wird nach dem Lese-;zugriff um 1 erhöht)
; Einsprung für 'Read Random1
read_rnd_seq:
09C1 3E FF LD A,OFFH
09C3 32 ODD3 LD (§read_or_write?)09C6 CD 04BB CALL get_record_#s
;Flag auf 'READ1
JsetzenfAJParameter aus dem;FCB übernehmen
203
BDOS-Listing
09C9 3A ODE3 LD
09CC 21 ODE1 LD
09CF BE
09D3 FE 80
CP
09DO DA 09E6 JP
CP
09D5 C2 09FB JP
;A = Gev;unschte Re-;cordnummer;HL -> Höchste Record-;nummer des letzten;Extends im FCB;Wird die gewünschte;Recordnummer noch vom;FCB abgedeckt ?
C,read_sequ_record;J: Record lesen
A,(§sequ_rec)
HL,§max_ext_rec
(HL)
128
NZ,end of file
09D8 CD 095A CALL open_next_extend
09DB AF XOR09DC 32 ODE3 LD
09DF 3A 0345 LD09E2 B7 OR
09E3 C2 09FB JP
A(§sequ_rec),A
Folgen noch mehrExtends ? (Ist diehöchste Recordnummerdes letzten Extendsgleich 128 ?)N: Fehler, Ende desFiles erreichtJ: Nächsten ExtendöffnenUnd Record Nummer 0des neuen Extendslesen
A,(§exit_value)A
NZ,end of file
;Wurde überhaupt ein;nächster Extend ge;funden ?;N: Fehler, Ende des;Files erreicht
; Record lesen•/read_sequ_record:•
09E6 CD 0477 CALL set §block
09E9 CD 0484 CALL check §block #
09EC CA 09FB JP Z,end of file
09EF CD 048A CALL set_§record#
09F2 CD 03D1 CALL set_dsk_trk_sec
09F5 CD 03B2 CALL read_record09F8 C3 04D2 JP update_record_#s
;Blocknummer des Re-;cords aus der Block-;tabelle holen.;lst der entsprechende;Eintrag in der Block-jtabelle belegt ?;N: Fehler, Ende desJFiles erreicht
;J: Absolute Record-Jnummer berechnenEntsprechende Spur;und Sektor anwählen,;Record lesen;und Parameter im FCB;aktualisieren
204
BDOS-Listing
; Ende des Files erreicht
end of file:
09FB C3 0305 read write error ;Fehler zurückmelden
; Fortsetzung von 'Write Sequential1
_write_sequ:•
09FE 3E 01 I,DOAOO 32 ODD5 LD
A,1 ;Sequential-Flag{§sequential?),A ;auf 1 setzen
;(Die Recordnurnmer;wird nach dem Lese-;zugriff um 1 erhöht)
.f JA- i-r 1 .it.-!. ••,*,:•*?>- ,',
; Einsprang für 'Write Random1
wri te__rnd_seq:
OA03 3E 00 LD
OA05 32 ODD3 LD
OA08 CD 0554 CALL
OAOBOAOE
A,0 ;Flag auf 'Write';setzen
{§read or v/rite?),A
- isk ro?
2A 0343CD 0547
L DCALL
HL,(§entry_word)fcb ro?
;Disk schreibge;schützt ?;M: HL -> FCB;File schreibge-;schützt ?
OA11 CD 043B CALL get_record_#s
OA14 3A ODE3OA17 FE 80
LDCP
A, ( §sequ__rec)1 28
OA19 D2 0305
OA1C CD 0477
JP
CALL
;N: Parameter aus dem;FCB übernehmen;ist die gewünschte;Recordnummer kleiner;als 128 ?;N: Fehler, Falsche;Recordnummer ange-;v/ählt
MC,read write error
set §block
OA1F CD 0484 CALL check §block #
JJ: EntsprechendejBlocknummer der;Blocktabelle ent-;nehmen;lst der Block schon;belegt ?
205
BDOS-Llsting
OA22 OE 00 T.r C,0
OA24
OA27
OA2A
OA2D
C2
CD
32
G]
OA6E
043E
ODD7
0000
JP
CALL
LD
LD
OA30 B7
OA3
OA34OA35OA36
OA39OA3A
CA OA3B
4FOBCD 045E
444D
OR
LDDECCALL
LDLD
M Z , norma l_wr i te
get_block_pos
(§block_pos), A
BC,0
Z,get new block
C t A3Cget__block #
3fHC,L
,? w •-• • • i
;C - BIOS-Flag fürjnormalen Schreib-; zugriff;J: Normaler Schreib-;zugriff;N: Position der neuen;Blocknummer in derjBlocktabelie berech-;nen und merken
;BC - zuletzt belegtejBlocknumrner, falls;ein neuer Eintrag an-gelegt werden muß;Ist die Tabellenposi-;tion der neuen Block-;nummer gleich Null ?;J: Die aktuelle;Blocktabelle ist be-;legt, es muß ein;neuer Eintrag ge-; schaffen v;eraen;N: BC - Neue Block-;position - 1;Letzte belegte Block-;nummer der Blockta-;belle entnehmen;BC = Nummer des zu-; letzt belegten Blocks
; Nächsten freien Block belegen; 3C = zuletzt belegte Blocknummer
get_new_block:
OA3BOA3EOA3FOA40
CD 07BE7D34C2 OA48
;Nachstgelegenen,;freien Block suchen
CALL allocate_next_blockLD A,L ;Freien Block gefun-OR H ;den ?JP NZ ,wri te_new_block; J: V7eiter
; Es konnte kein freier Block mehr gefunden werden.; 'Disk voll' melden
disk_full:•
OA43 3E 02 L0
OA45 C3 0301 JP
A,2
return__byte
;A = Fehlercode für;'Disk voll';Fehlercode zurück-geben
206
BDOS-Listing
; Record in den neu belegten Block schreiben
write new block:
OA48OA4BOA4COA4FOA52
22EB2A0109
ODE5
03430010
LDEXLDLDADD
OA53 3A ODDD LDOA56 B7 OROA57 3A ODD? LD
OA5A CA OA64 JP
(§block_#),HLDE,HLHL,(§entry_wordBC,pos_dxHL, BC
A,(§large_dsm?)AA,(§block_pos)
Z,new_block_word
OA5D CD 0564 CALL add hi a
OA60 73 LDOA61 C3 OA6C JP
(HL),Efirst write
;Blocknummer merken;DE - Blocknummer
-> FCB
;HL -> Blocktabelle
;Sind die Blocknummern;1 6-Bit Werte ?;A - Position des neu-;en Blocks in derjBlocktabelle;J: Blocknummer als; 16-Bit Wert eintragen
;N: Blocknummer als; 8-Bit Wert eintragen;HL -> Blocktabelle +jPosition;Blocknummer eintragen;und Record als ersten;Record des neuen;Blocks schreiben
; Neue Blocknummer als 16-Bit Wert eintragen•inew block word:
OA64OA65OA67OA68
4F06 000909
LDLDADDADD
C,A .B,0HL,BCHL,BC
OA69OA6AOA6B
732372
LDINCLD
(HL),EHL(HL),D
;BC = Position des;neuen Blocks;zv/eimal aufaddieren; da jeder Block zwei; Bytes in der Block-; tabelle belegt;LSB der Blocknummer; eintragen;MSB der Blocknummer; eintragen
207
BDOS-Listing
; Der zu schreibende Record, ist eler erste Record eines neuen: Blocks
first write:
OA6C OE 02 LD C,2 ;C - BIOS-Flag fürjZugriff auf neuen;Block
; Record schreiben•/; C - Record-Flag; - 2 , falls der Record in einem neuen Block liegtt = 0 sonst
normalwrite:
OA6E
OA71
OA72
OA73OA74
OA77OA7AOA7B
3A 0345
B7
CO
C5CD 048A
3A ODD53D3D
LD
OR
RET
PUSHCALL
LDDECDEC
A, ( §exit value )
A
N Z
BCset_§record#
A, ( §sequential? )AA
OA7C C2 OABB JP
;A - vorheriger Feh-; lercode;War vorher ein Feh-; ler ?;J: Schreibzugriff;abbrechen
;N: Record-Flag retten;Absolute Recordnummer;berechnen. HL = Re-Jcordnummer;A - Zugriffsart;ist die Zugriffsart;gleich 2 ?;N: Daten schreiben
NZ,write actual data
Der Block soll vorher mit OOH('Write Random with Zero Fill
OA7F C1OA80 C5OA81 79OA82 3DOA83 3D
rPOP BCPUSH BCLD A,CDEC ADEC A
gefüllt werdent \
1 4 - «.
;Record;und wi;A = Re;Gilt d: zugrif
OA84 C2 OABB JP
Record-Flag: der Schreib-:iff dem ersten
;Record eines neuen;Blocks ?;(Record-Flag = 2 ?);N: Der Block ist be-Jreits initialisiert
NZ,write actual data
208
BDOS-Listing
OA87 E5 PUSH HLOA88 2A ODB9 LD HL,(?§dirbuf)OA8B 57 LD D,A
;J: Kompletten Block;schreiben;Recordnummer retten;HL -> DIRBUF;D - 0 (Zähler)
; DIRBUF mit OOH füllen
zero write buffer:
OA8COA8DOA8E
77231 4
LDINCINC
OA8F F2 OA8C JP
(HL),A ;OOH einsetzenHL ;Bufferzeiger +1D ;Zähler +1
;Zähler < 128 ?;Weiter, bis;Zähler = 128
P,zero write buffer
; Den auf 0 initialisierten DIRBUF in den neuen Block; schreiben
OA92
OA95
OA98 OE 02
CD 05EO CALL set_dma_to_dirbuf ;DMA-Adresse;setzen
2A ODE7 LD HL,(§blkrecord) ;HL - Absolute;Recordnummer des;ersten Records im;neuen Block;C = BIOS-Flag für
DIRBUF
LD C,2
block_write_loop:
OA9A
OA9DOA9E
OAA1
OAA2
OAA5
OAA8
22
C5CD
C1
CD
2A
OE
ODE5
03D1
03B8
ODE5
00
LD
PUSHCALL
POP
CALL
LD
LD
(§abs_rec_#),HL
BCset_dsk_trk_sec
BC
write_record
HL,( §abs_rec__#)
C,0
;'Erster Schreibzu-;griff auf einen;neuen Block1
;Recordnummer spei-;ehern;3IOS-Flag retten;Track und Sektor an-;wählen;BIOS-Flag zurück
;(Null-)Record schrei-;ben
;HL = Nummer des ge-;schriebenen Records;C = BIOS-Flag für den;nächsten Schreibzu-;griff
209
BDOS-Listing
OAAA
OAAD
OAAE
3A ODC4 LD
OAB1
OAB4
OAB5
OAB8
47
A5
OAAF B8
OABO 23
E1
LD
AND
CP
INC
C2 OA9A JP
POP
A,(§blm)
B,A
;A - Anzahl der Re-;cords pro Block -1;B = A
L ;A - Geschriebene;Recordnummer modulo;Anzahl der Records;pro Block
B ;Alle Records des;neuen Blockes ge-;schneben ?
HL ;Recordnummer + 1;N: Nächsten (Null-);Record schreiben
NZ, block_write__loop
HL
22 ODE5 LD (§abs_rec_#),HL
CD 05DA CALL restore dma
;J: Recordnummerjzuruck;Recordnummer spei-;chern;DMA-Adresse auf alten;Uert setzen
; Tatsächliche Record-Daten schreiben
write actual data:
OABB CD 03D1 CALL set dsk trk sec
BCBCwrite_recordBC
A, (§sequ rec)
OABEOABFOACOOAC3
C1C5CDC1
03B8
POPPUSHCALLPOP
~ .. i i-t 1. «*
;Track und Sektor an-;v/ählen;Record-Flag zurück;und wieder retten;Record schreiben;Record-Flag zurück
OAC4 3A ODE3 LD
OAC7 21 ODE1 LD
OACA BE CP
OACB DA OAD2 JP
;A = Nummer des ge-;schriebenen Records;innerhalb des aktu-;ellen Extends
HL,§max_ext_rec ;HL -> maximale Re-;cordnummer des aktu-;ellen Extends
(HL) ;Liegt der geschrie-;bene Record noch imJaktuellen Extend ?;j; Die Filelänge wur-;de nicht verändert
C,still in current ext
210
BDOS-Listing
OACE 77 LD
OACF 34
OADO OE 02 LD
still in current ext
(OAD2 OD DEC(OAD3 OD DEC(OAD4 C2 OADF JP
OAD7 PUSHOAD8 CD 0569 CALL
OADB E6 7F AND
OADD 77 LDOADE F1 POP•/test__rec_#:»
OADF FE 7F CP
OAE1 C2 OBOO JP
OAE4 3A ODD5 LDOAE7 FE 01 CP
OAE9 C2 OBOO JP
(HL),A
(HL)
C,2
C )c )NZ,test rec #)
AFget_eg
07FK
(HL),AAF
;N: Neue Recordnummer; im FCB merken;und Filelänge um;einen Record er-;weitern;C = Record-Flag für;den folgenden Test
;In neueren BDOS-Ver-;sionen, stehen an den;nachsten 5 Bytes;'NOP' (i)
;Wurde ein neuer Block;begonnen ? (C - 2 ?);M: weiter;J: 'File verändert1
; setzen
;Recordnurnmer retten;Adresse des 'NA1-Flag;holeny'File geändert1 set-; zen;Flag zurückschreiben;Recordnummer zurück
127 ;War der geschriebene;Record, der letzte Re-
•'• • . -x i . - ;cord des aktuellenjExtends ?;N: Write beenden
NZ,j p_update_record_#s
A,(§sequential?) ;War der Schreibzu-1 ;griff sequentiell ?
;N: V/rite beendenNZ,j p_update_record_#s
21 1
BDOS-ListJ ng
; Nächsten Extend für den nächsten sequentiellen Schreib-; zugriff eröffnen•/OAEC CD 04D2 CALL update_record_#s ;Neue Recordnummer im
;FCB speicnernOAEF CD 095A CALL open_next_extend ;Nächsten Extend er-
;öffnen
OAF2 21 0345 LD
OAF 5OAF 6
7EB7
LDOR
OAF7 C2 OAFE JP
HL,§exit_value ;HL -> Fehlercode vom;'open'-Aufruf
A,(HL) ;A - FehlercodeA ;Konnte ein nächster
; Extend eröffnet wer-;den ?;N: Fertig, der Fehler;wird erst beim näch-;sten ' V/rite ' -Auf ruf;gemeldet
NZ,clear_exit_value
OAFAOAFB
3D32 ODE3
DECLD
A(§sequ_rec), A
;J: Recordnummer auf;-1 setzen, da der;'update__record_#s'-;Aufruf die Record-jnummer um 1 erhöht;und somit die Record'jnummer auf 0 setzt
; Fehlercode löschen•tclear exit value:
OAFE 36 00 LD (HL),0 ^Fehlercode auf 'kein;Fehler' setzen
; Neue Recordposition wieder in den FCB einsetzten.; Nach eine sequentiellen Zugriff, wird eine um 1 erhöhte; Recordposition eingesetzt.
-,-. .* -
j p_update__record_#s :
OBOO C3 04D2 JP update record
212
BDOS-Listing
; UPRO far 'Read Randon1, 'Write Random1•/; Random Record Nummer (RRN) in die entsprechende; sequentielle Record Nummer (SRN) umrechnen.•/; I: §entry_v;ord -> FCB mit gesetzter Random Record Nummer; C - OOH, falls der Aufruf von 'Write Random1 kam; C - FFH, falls der Aufruf von 'Read Random1 kam•i•t O: §entry_word -> FCB mit Sequentieller Record Nummer; §exit_value - Fehlercode•itrans_rnd_to_seq:•
OB03 AF XOR A ;Zugriffsflag aufOB04 32 ODD5 LD - (§sequential?),A ;'Random' setzen
; Einsprung für 'Write Random With Zero Fill'
zero trans r to s :
OB07 C5 PUSH BC
OB08030BOBOCOBOF
OB1 0OB1 1
OB1 3
OB1 4OB1 5
OB1 6OB17OB18
2AEB211 9
7EE6
F5
7E17
237E17
0343 LDEX
0021 LDADD
LD7F AND
< . . .. * . . •«» f ' i
PUSH
LDRLA
INCLDRLA
HL,(§entry word)DE , HLHL,pos rOHL,DE
A , ( HL)07FH
^ C -., J •. ' " * '..** ~»*f,~f v~*
AF
A, (HL)
HLA,(HL)
OB19 E6 1F
OB1B 4F
AND 01FH
LD C,A
;Schreib/Lesekennung;retten
;DE -> FCB
;HL -> LSB der RRN
;A = LSB der RRN;RRN modulo 128 be-jrechen. Dies ist dieJRecordnummer inner-;halb des berechneten^Extends;Recordnummer retten
;A = LSB der RRNJHöchstes Bit ins;CY-Flag schieben;HL -> MSB der RRN;A - MSB der RRN;Höchstes Bit des;LSBs nach Bit 0Jschieben. Dies er-;gibt RRN / 128;(RRN / 128) mod 32;ist die Extendnummer;C = Extendnummer
21 3
BDOS-Listing
OB1COB1DOB1EOB1FOB20OB21
OB23
OB24
OB25
OB26OB27OB28GB29
OB2B
7E1FIF1F1FE6 OF
47
F1
23
6E2C2D2E 06
C2 OB8B
LDRRARRARRARRAAND
LD
POP
INC
LDINCDECLD
„
JP
A, (HL)
OOFH
B,A
AF
HL
L, (HL)LLL, 6
H» .. r —-a ->J> >. • u. J. . .
NZ,rnd seek_error
;A - MSB der RRN; /2; /4; /s; /16 (-RRN / 4096)^Oberste 4 Bits lö-;schen, da rotiert;wurde;B - RRN / 4096; - RRN / (32 * 1 28); - Extendgruppen-; Nummer der SRNjRecordnummer im Ex-; tend zurück
;HL -> Überlauf; der RRN;Ist das Überlauf-; byte ungleich; Null ?;L - Fehlercode 'Seek;past physical end of• n i c?\t ', LJ -L o JV
;J: Fehler melden
; Errechnete SRN im FCB abspeichern: DE -> FCB
OB2E 21 0020 LDOB31 19 ADD
OB32 77
OB33OB36
21 OOOC19
OB37 79
LD
LDADD
LD
. a„ OB38 96 J1(.4 SUB
OB39 C2 OB47 JP
HL,pos__crHL, DE
(HL),A
HL,pos_exHL, DE
JHL -> Recordnummer;im FCB;Recordnummer im FCB;speichern
;HL -> Extendnummer;im FCB
A,C ;A - Errechnete Ex-;tendnummer
(HL) ... -i ••«•.•-** ... ;lst der errechnete;Extend schon ge-jöffnet ?;N: Extend neu öffnen
NZ,different extend
214
BDOS-Listing
OB3C 21 OOOE LD
• - > '.f
OB3FOB40
1 978
OB41 96
OB42 16 7F
ADDLD
SUB
AND
OB44 CA OB7F J!
HL,pos_egHL, DE ;KL -> ExtendgruppeA,B ;A - Errechnete Ex-
; tendgruppen-Mummer(HL) ;Ist diese Extend-
;gruppe schon;geöffnet ?
07FH -Bit 7 (FCB-Flag ver-jnachlässigen);J: Der gewünschte Re-;cord liegt im aktuell^geöffneten Extend
Z,correct rnd access
; Die gev/ünschte Recordnummer liegt in einem anderen Extend.; Dieser Extend muß noch geöffnet v/erden. --.;,,..-.. ,..-..*..,.,,.. «„,,_ s, ..r.
different extend:
OB47 C5
OB48 D5
OB4C D1OB4D C1
OB4E 2E 03
OB50OB53
3A 03453C
OB5A 19
OB5B 71
PUSH BC
PUSH DEOB49 CD 08A2 CALL
POPPOP
LD
LDINC
OB54 CA OB84 JP
OB57 21 OOOC LDADD
LD
OB5C 21 OOOE LDOB5F 19 ADD
OB60 70 LD
close file
;Extendnummer und Ex-;tendgruppennummer;retten;FCß-Zeiger retten;Aktuellen Extend;schliessen;FCB-Zeiger zurückjExtendnummer und Ex-;tendgruppen-NummerJzurück;L = Fehlercode;'Cannot Close CurrentJExtend';ist ein Fehler beim;Close-Aufruf aufge-;treten ?
Z,bad_rnd_access ;J: Fehler melden
DEBC
L,3
A,(§exit_value)A
HL,pos_exHL, DE
(HL),C
HL,pos_egHL, DE
(HL),B
;HL -> Extendnummer;im FCB;Neue ExtendnummerJeinsetzen
;HL -> Extendgruppen-;Nummer im FCBJNeue Extendgruppen-;Nummer einsetzen
215
BDOS-Listing
OB61OB64OB67
CD 08513A 03453C
CALLLDINC
__open_f ileA, (§exit_value)A
OB68 C2 OB7F JP
;Neuen Extend öffnen;Konnte der neue Ex-;tend geöffnet wer-;den ?;J: 'Kein Fehler1
jmeldenNZ,correct rnd access
; Der neue Extend konnte nicht geöffnet werden
OB6B C1 POP
OB6C C5OB6D 2E 04
OB6F OC INC
OB70 CA OB84 JP
BC
PUSH BCLD L, 4
;Schreib/Lesekennung; zurück;und wieder retten;L - Fehlercode 'Seek;To Unwritten Extend1
jHandelt es sich um;eine Lesezugriff ?
Z,bad_rnd_access ;J: Fehler melden
C
; Neuen Eintrag zur Erweiterung des Files erzeugen; (Nur bei einem Schreibzugriff) .,,.,.,..•tOB73 CD 0924 CALL _make_file ;N: Neuen Eintrag er-
jöffnen, der neue Ex-;tend wird vom alten^Eintrag nicht mehr;abgedeckt;L = Fehlercode 'Cant;Create New Extend';Konnte ein neuer Ein-;trag geschaffen wer-fen ?
Z,bad_rnd_access ;N: Fehler melden
OB76 2E 05
OB78OB7B
3A 03453C
LD
LDINC
L,5
A,(§exit_value)A
OB7C CA OB84 JP
; Der gewünschte Record bzw. Extend wurde gefunden; und ist geöffnetr
correct rnd access:
OB7F C1 POP BC
OB80 AF XOROB81 C3 0301 JP
Areturn__byte
jSchreib/Lesekennung; zurück;Fehlercode 0; zurückmelden
216
BDOS-Listing
; Der letzte Extend konnte nicht geschlossen oder; der neue Extend nicht eröffnet werden
bad rnd access:
OB84OB85
E5CD 0569
OB88 36 CO
*••"•• OB8A E1
PUSHCALL
LD
POP
HLget_eg
(HL),OCOH
HL
;Fehlercode (L) retten;Adresse des FCB-Flags;holen;Obere zwei Bit setzen;(File als 'unverän-;dert' markieren und;als Fehlerkennung die;Extendgruppennummer;auf 64 setzen);Fehlercode (L) zurück
; Fehlerhafte Random Record Nummer angegeben
rnd seek error:
OB8B C1
OB8COB8D
7D32 0345
POP
LDLD
OB90 C3 0578 JP
A, L(§exit_value),A
not altered
;Schreib/Lesekennung; zurück;A - Fehlercode;Fehlercode zurück-;melden;und 'File unver-;ändert' setzen
; Fortsetzung von 'Read Random1
read random:
OB93OB95
OE FF LD C,OFFH ;C = LesekennungCD OB03 CALL trans_rnd_to_seq ;RRN in SRN umrechnen
^Fehler ?OB98 CC 09C1 CALL Z,read_rnd_seq ;N: Record lesenOB9B C9 RET
Fortsetzung von "Write Random1
_write_random:•
OB9C OE 00OB9E CD OB03
LD C,0CALL trans_rnd_to_seq
OBA1 CC OA03 CALL Z , write_rnd_seqOBA4 C9 RET
;C = Schreibkennung;RRN in SRN umrechnenJFehler ?;N: Record schreiben
217
BDOS-List i rig
; UPRO für 'Set Random Record' und 'Compute File Size1
«/; Sequentielle Record Nummer (SRN) in die entsprechende; Random Record Nummer (RRN) umrechnen und in den FCB ein-; setzen.
; i: DE - Position der umzurechnenden Recordnummer im FCBJ - Position der aktuellen Recordnummer (pos_cr); (für 'Set Random Record1); =-- Position der höchsten Recordnummer (pos_rc); (für 'Compute File Size1); HL -> FCB•/; O: BC - Errechnete Random Record Nummerj = 32 * 128 * Extendgruppe + 128 * Extendnummer; + Recordnummer; A Überlaufbyte der RRN; - 0, falls die RRN kleiner als 65536 ist
l
1 , sons
trans_seq__to_rnd:'* ''OBA5OBA6
OBA7OBA8
OBAAOBADOBAEOBAF
EB19
4E06 00
21 OOOC197EOF
EXADD
LDLD
LDADDLDRRCA
DE , HLHL, DE
C , ( HL )B,0
HL, po s exHL, DEA, (HL)
OBBO E6 so AND 080H
OBB2OBB3
... 03B4OBB603B7OBB8OBB9OBBA
•»
OBBCOBBD
814F3E 0088477EOFE6 OF
8047
ADDLDLDADCLDLDRRCAAND
ADDLD
A,CC,AA,0A, BB, AA, (HL)
OOFH
A, BB, A
;HL -> aktuelle oder;höchste Recordnummer
;BC - Recordnummer
HL -> ExtendnummerA = ExtendnummerBit 0 nach Bit 7 ro-tierenund restliche Bitslöschen ergibt:Extendnummer * 1 28BC = BC + ANiedrigstes Bit derExtendnummer zurbisherigen RRNhinzuaddierenA = Extendnummer/ 2
Restliche Bits lö-schen, da rotiertwurdeRestliche Bits derExtendnummer zurRRN addierenBC = Recordnummer+ 1 2 8 * Extendnummer
218
BDOS-Listing
OBBEOBC1OBC2
OBC3OBC4OBC5OBC6OBC7
OBC803C9
OBCA
OBCBOBCCOBCD
21 OOOE19IE
87878787F5
8047
F5
E17DE1
LDADDLD
ADDADDADDADDPUSH
ADDLD
PUSH
POPLDPOP
KL,pos_egHL , DEA , ( HL )
A, AA, AA, AA, AAF
A, BB, A
AF
HLA, LHL
OBCE B5
OBCF E6 01
OBD1 C9•r
OR
AND
RET
0 1 H
r
; Fortsetzung von 'Compute File Size1•r"r Random Record Nummer des letzten ( i ): berechnen
__compu t e_f i l e_s i z e:
OBD2 OE OC LD C,12
OBD4 CD 0718 CALL search dir first
;HL -> Extendgruppe;Nummer der Ex tend-;gruppe holen
;A - Extendgruppe ** 2* 4* 8* 16
;Eventuelle Überlauf-jkennung im CY-Bit;retten;Extendgruppe * 16 zum;MSB der bisher er-;rechneten Recordnum-;mer addieren.;Dies entspricht derjAddition von 16*256*;Extendgruppe und er-jgibt in BC die tat-; sächliche RRN
;CY-Flag von der letz-;ten Addition über den;Stack nach L kopieren;A - CY-Flag;CY-Flag von der S2-;Multiplikation zurück;Trat bei einer der;letzten beiden arith-jmetischen Operationen;ein Überlauf auf ?;j: A = 1;N: A = o
Records im File
;Nur Usernummer, File-Jnamen und Filetype;vergleichen;Ersten passenden Ein-Jtrag suchen
219
BDOS-Listing
OBD7 2A 0343 LDOBDA 11 0021 LDOBDD 19 ADD
03DE E5 PUSHOBDF 72 LDOBEO 23 INCOBE1 72 LDOBE2 23 INCOBE3 72 LD
HL, ( §entry_worclDE,pos_rOHL,DE
HL(HL),DHL(HL),DHL(HL),D
;HL ->;D = o;HL ->
FCB
LSB der Random^Record Nummer des
;RRN-Zeiger retten;RRN im FC3j rnit;Null; vorbe-; setzen
F
; Alle zum FCB passenden Einträge durchsuchen und die; höchste gefundene sequentielle Record Nummer als: Random Record Nummer in den FCB einsetzen
compu te_s i z e_loop
OBE4 CD 05F5 CALLOBE7 CA OCOC JP
OBEA CD 055E CALL
OBED 11 OOOF LD
OBF3OBF4OBF5
all_entriesZ,pop_hl
;Noch einen weiteren;Eintrag gefunden ?
_compared?;N: RRN-Zeiger vom;Stack nehmen, Fertig
lS
get_entry_pointer ;J: Zeiger auf den ge-;fundenen Eintrag;holen
DE,pos_rc
OBFO CD OBA5 CALL trans_seq_to_rnd
E1E55F
POPPUSHLD
HLHLE,A
;DE - Position der;höchsten Recordnummer;im gefundenen EintragDazugehörige RRN be-;rechnen;RRN-Zeiger zurück;und wieder retten;EBC = Errechnete RRN
;lst
OBF6OBF7OBF8OBF9OBFAOBFBOBFCOBFD
799623789E237B9E
LDSUBINCLDSBCINCLDSBC
»&?>« ,<» .. i *
A,C(HLHLA, BA, (HLA, EA, (
OBFE DA OC06 JP
HL)
HL)
C,not_greater
die errechneteJRRN größer als dieJbisher im FCB ein-;getragene RRN ?;LSB der RRN ver-gleichen
;MSB der RRN ver-;gleichen
;Überlaufbyte der;RRN vergleichen;Größere RRN gefunden?;N: Nächsten Eintragjüberprüfen
l
220
BDOS-Listing
OC01OC02OC03OC04OC05
732B702B71
LDDECLDDECLD
(HL),EH L(HL ) ,BHL(HL),C
;J: Errechnete RRN; als neue; größte RRN; im FCB; speichern
; Nächsten Eintrag suchen
not_greater:?OC06 CD 072D CALL search dir next
OC09 C3 OBE4 JP
jNächsten passenden;Eintrag suchen
compute_size_loop ;und dessen höchste;Recordnummer über-prüfen
/- . •*.,«< «^1-,
; Ende von __compute_f i le_size
pop_hl:
OCOC E1
OCOD C9
POP
RET
HL ;RRN-Zeiger vom Stack;nehmen;Fertig
. **** BDOS-Funktion Nummer 36 'Set Random Record1
?set_random_record :•
OCOE 2A 0343 LDOC1 1 11 0020 LD
HL, ( §entry_word )DE,pos_cr
OC14 CD OBA5 CALL trans_seq_to_rnd
HL,pos_rOHL, DE(HL),CHL(HL),BHL(HL),A
OC1 7OC1 AOC1BOC1COC1DOC1EOC1F
21 0021197123702377
LDADDLDINCLDINCLD
OC20 C9 RET
;HL -> FCB;DE = Position der;aktuellen Record-jnummer im FCB;Random Record Nummer;des aktuellen Records;berechnen
;HL -> RRN des FCB;LSB der RRN;speichern;MSB der RRN;speichern;Überlaufbyte;speichern
221
BDOS-Listing
; UPRO für 'Select Disk'; Neue Disk anwählen
I: §bdos_disk - Nummer der anzuwählenden Disk
0: -
login_disk:
;HL - Login-VektorOC21OC24OC27OC28
OC2BOC2COC2D
2A ODAF3A 03424FCD 04EA
E5EBCD 0359
OC30 E1
LD HL,(§login_vecLD A,(§bdos_disk)LD C,ACALL shift right hi
PUSH HLEX DE,HLCALL physical_select
POP HL
OC31 CC 0347 CALL Z,select error
OC34OC35
7D1F
LDRRA
A,L
OC36 D8 RET
HL, ( §login__vec)C,LB,Hset disk vec
OC3F 22 ODAF LD (§login_vec),HL
OC42 C3 06A3 JP logical_select
OC37OC3AOC3BOC3C
2A4D44CD
ODAF
050B
LDLDLDCALL
;C =» Disknummer;Entsprechendes Bit;des Login-Vektors;nach L,0 schieben.;Login-Bit retten;E,0 - Login-Bit;Disk selektieren;und DPH/DPB über-; nehmen;Login-Bit zurück;Fehler beim physical_jselect ?;J: Fehler melden
;A,0 - Login-Bit;Login-Bit ins CY-Flag; schieben.;War die Disk bereits;vorher selektiert ?;J: Fertig
;N: ALV und CSV neu;setzen
;BC = Alter Login-;Vektor;Bit der neuen Disk imJLogin-Vektor setzen;und neuen Login-jVektor speichern;CSV und ALV setzen
222
BDOS-Listing
r
. **** BDOS-Funktion Nummer 14 'Select Disk1
; I: §entry-byte - Disknumrner
?select_disk:•
OC45 3A ODD6 LDOC48 21 0342 LD
OC4B BE
OC4C C8
OC4D 77
CP
RET
LD
OC4E C3 OC21 JP
A,(§entry_byte)HL, §bdos_disk
(HL)
(HL),A
login_disk
;A - Disknummer;KL -> aktuelle Disk;nummer;Soll die aktuelle;Disk angewählt wer-fen ?;J: Fertig
;N: Heue Disknummer;als aktuelle Disk-;nummer speichern;uncl neue Disk an-;wählen
; UPRO für alle Filefunktionen•r•r Die irn FCB angegebene Disk selektieren und die aktuelle; Usernumrner in den FCB eintragen•r•r I: §entry_word -> Diskcode (im FCB)•t; 0: §entry_word -> Aktuelle Usernummer (im FCB)
auto select:
OC51 3E FF
OC56OC59 7EOC5A E6 1F
LDOC53 32 ODDE LD
2A 0343 LDLDANDDECOC5C 3D
OC5D 32 ODD6 LD
OC60 FE 1E CP
OC62 D2 OC75 JP
A,OFFH ;Flag für ?bdos_exit(§file_func?),A ;auf 'File-Funktion1
;setzen
EL,(§entry_word) ;HL -> DiskcodeA,(HL) ;A = Diskcode01FH ;0bere 3 Bits löschenA ;und Diskcode in Disk-
;nummer umrechnen(§entry_byte),A jDisknummer für even-
;tuellen 'Select'-Auf•Jruf speichern
01 EH ;War der Diskcode;= '?' oder 0 ?
NC,no_auto_slct ;J: Keine Disk extrajanwählen
223
BDOS-Listing
OC65OC68
3A32
0342ODDF
OC6F E6 EO
OC71 77
no auto slct:
OC75OC78OC7BOC7COC7D
3A 03412A 0343B677C9
LDL D
OC6B 7E LDOC6C 32 ODEO LD
AND
LD
OC72 CD OC45 CALL
L DLDORLDRET
A, (§bdos disk) ;Aktuelle Disknummer(§old_bdos_disk),A;für '?bdos_exit'
; speichern
A,(HL) ;NeuG Disknummer(§old_fcb_disk),A ;fur '?bdos_exit'
;speichernOEOH
(HL),A
?select disk
A, ( §user__#)HL,(§entry_word)(HL)(HL),A
;Disknummer auf 0;oder, falls der;Diskcode '?' war,;auf 2011 setzenjDisknummer in FC3;einsetzen;Neue Disk anwählen
;A - Usernummer;HL -> FCB;Usernummer in den;FCB einsetzen
. **** BDOS-Funktion Nummer 12 'Return Version Number1
?return_version_#:•
OC7E 3E 22 LDOC80 C3 0301 JP
A,version_#return byte
; Vers ion snurnmer; zurückgeben
**** BDOS-Funktion Nummer 13 'Reset Disk System'
?reset_disk_system:
OC83OC86OC89OC8COC8DOC90OC93OC96
212222AF322122CD
0000ODADODAF
03420080ODB105DA
LDLDLDXORLDLDLDCALL
OC99 C3 OC21 JP
HL,0(§ro_yec),HL(§login_vec),HLA(§bdos_disk),AHL,§buffer
;HL = o;R/O-Vektor undjLogin-Vektor löschenJAktuelle Disknummer •;auf 0 setzen;DMA-Adresse auf
(§dma_address),HL Standardwert setzenrestore_dma ;Und dies auch dem
;BIOS mitteilenlogin_disk ;Disk A: (für SUBMIT)
;anwahlen
224
m
BDOS-Listing
W
• **** BDOS-Funktion Nummer 15 'Open File
?open_file:•
OC9C CD 0572 CALL zero eg
OC9F CD OC51 CALLOCA2 C3 0851 JP
auto_selectooen file
jExtendgruppe auf;Null setzen;Disk selektieren;und File öffnen
. **** BDOS-Funktion Nummer 16 'Close File'
?close_file:•OCA5 CD OC51 CALLOCA8 C3 08A2 JP
auto_selectclose file
;Disk selektieren;und File schliessen
w
. **** BDOS-Funktion Nummer 17 'Search for First1
?search first:
OCAB OE 00 LD
OCB4
OCB7
OCB8OCBA
OCBDOCCO
CD
7E
FEC4
CDOE
04A6
3F0572
OC51OF
CALL
LD
CPCALL
CALLLD
search now:
OCC2 CD 0718 CALL
OCC5 C3 05E9 JP
C,0
OCADOCAEOCAFOCB1
EB7EFECA
3FOCC2
EXLDCPJP
DE, HLA, (HL)i ? i*
Z , sear
;C - Anzahl der zuVergleichenden Bytes;HL -> FCB;Diskcode holenjDiskcode - '?' ?;J: Beliebigen Eintragjsuchen; Es braucht;kein Byte (C ist 0 l)^zwischen FCB und Ein-Jtrag übereinzustimmen
get_extend_pointer;N: Adresse der Ex-Jtendnummer holen
A,(HL) JA = Gewünschte Ex-; tendnummer
'?' JExtendnummer = '?' ?NZ,zero_eg ;N: Extendgruppe auf
JNull setzenauto_select JDisk anwählenC,15 ;Alle Bytes Eintrags
;vergleichen
search_dir_first JErsten passenden Ein-;trag suchen
move_dirbuf_to_dma;und Directory-RecordJdes gefundenen Ein-;trags zur DMA-Adresse;kopieren
225
BDOS-Listing
• **** BDOS-Funktion Nummer 18 'Search for Next1
?search next:
OCC8 2A ODD9 LD
OCCB 22 0343 LD
OCCE CD OC51 CALL auto select
OCD1 CD 072D CALL search dir next
HL,{?§search_fcb) ;HL -> FCB vom letzten;'Search for First'-;Aufruf
(§entry_word),HL ;Es wird der nächste,;zu diesem FCB passen-;de Eintrag gesucht;Disk anwählen
OCD4 C3 05E9 JP
;Nächsten passendenjEintrag suchen
move__dirbuf_to_dma ;und Directory-Record;des gefundenen Ein-;trags zur DMA-Adressejkopieren
. **** BDOS-Funktion Nummer 19 'Delete File1
?delete_file:rOCD7 CD OC51 CALLOCDA CD 079C CALL
OCDD C3 0701 JP
auto_selectdelete files
;Disk anwählen;Alle passenden;Einträge löschen
return_found_flag ;und Fehlercode;zurückgeben
- **** BDOS-Funktion Nummer 20 'Read Sequential1
?read_sequ:
OCEOOCE3
CD OC51C3 09BC
CALL auto_selectJP _read_sequ
JDisk anwählen;und nächsten sequen-;tiellen Record lesen
/•// BDOS-Funktion Nummer 21 'Write Sequential1
?write_sequ:
OCE6OCE9
CD OC51C3 09FE
CALL auto_selectJP _write_sequ
;Disk anwählenJund nächsten sequen-jtiellen Record;schreiben
•$ *
226
BDOS-Listing
. **** BDOS-Funktion Nummer 22 'Make File1
?make file:
OCEC CD 0572 CALL zero eg
OCEF CD OC51 CALLOCF2 C3 0924 JP
auto_selectrnakefile
;Extendgruppe auf;Null setzen;Disk anwählen;und neuen Eintrag;erzeugen
!*•' i'l
. **** BDOS-Funktion Nummer 23 'Rename File1
7?rename_f ile :•
OCF5 CD OC51 CALL auto_selectOCF8 CD 0816 CALL renamef i le
OCFB C3 0701 JP
;Disk anwählen;Alle passenden Ein; träge umbennenen
return_found_f lag ;und Fehlercode; zurückgeben
. **#* BDOS-Funktion Mummer 24 'Return Login Vector1
?return_login_vec:•rOCFE 2A ODAF LDOD01 C3 OD29 JP
HL , ( §login_vec ) ;HL = Login-Vektorreturn_word ; 16-Bit Wert zurück
;geben
g
, •.<,-.,, ; **** BDOS-Funktion Mummer 25 'Return Current Disk'
?return_disk :•
OD04 3A 0342 LDOD07 C3 0301 JP
A, ( §bdos_disk )return_byte
;A = Disknummer;8-Bit Wert zurück;geben
; **** BDOS-Funktion Nummer 26 'Set DMA Address*
?set_dma:•rODOA EB EXODOB 22 ODB1 LDODOE C3 05DA JP
DE,HL ;HL - Neue DMA-Adresse( §dma_address ) , HL JDMA-Adresse speichernrestore_dma ;und dem BIOS mit-
; teilen
227
BDOS-Listing
. -t*** BDOS-Funktion Nummer 27 'Get Addr (Ailoc)'
?get_allocation_addr•
OD11 2A ODBF LDOD14 C3 OD29 JP
HL,(?§alv)return word
;KL -> ALV; 16-Bit Wert zurück-;geben
• **** BDOS-Funktion Nummer 29 'Get R/O-Vector'
?get_ro__vec:•
OD17 2A ODAD LDOD1A CZ OD29 JP
ML,(§ro_vec)return word
;HL - R/O-Vektor; 16-Bit Wert zurück-;geben
; **** BDOS-Funktion Nummer 30 'Set File Attributes'
?set_file_attr:•rOD1D CD OC51 CALLOD20 CD 083B CALL
OD23 C3 0701 JP
auto_selectset file attr
;Disk anwählen;FCB in den Eintrag;übernehmen
return_found_flag ;und Fehlercode; zurückgeben
• **** BDOS-Funktion Nummer 31 'Get Addr (Disk Farms)1•r?get_parameter_addr:W
OD26 2A ODBB LD HL,(?§dpb) ;HL -> DPB
; UPRO für verschiedene BDOS-Funktionen•if 16-3it Wert zurückgeben
return word:
OD29OD2C
22 0345C9
LD (§exit_value),HL ;16-Bit Wert speichernRET ;Rücksprung nach
;?bdos_exit
228
BDOS-Listing
. **** BDOS Funktion Nummer 32 'Set/Get User Code1
?set_get_user_code:•
OD2D 3A ODD6 LDOD30 FE FF CPOD32 C2 OD3B JP
OD35OD38
3A 0341C3 0301
LDJP
A,(§entry_byte)OFFH
;A - Neue Usernummer;Usernummer holen ?
NZ,set_user_code ;N: Neue Usernummer;speichern
A,(§user_#)return byte
;J: Usernummer als;8-Bit Viert zurück-geben
; Neue Usernummer speichern
set user code:
OD3BOD3DOD40
E6 1F32 0341C9
ANDLDRET
01FH(§user_#),A
;Usernummer modulo 32;speichern
. **** BDOS-Funktion Nummer 33 'Read Random1•tTread random:
OD41 CD OC51 CALLOD44 C3 OB93 JP
auto_selectread random
JDisk anwählen;und Record lesen
. **** BDOS-Funktion Nummer 34 'Write Random'
?write_random:•
OD47 CD OC51 CALL auto_selectOD4A C3 OB9C JP write random
;Disk anwählen;und Record schreiben
. **** BDOS-Funktion Nummer 35 'Compute File Size1
?compute_f ile_s i ze:•/OD4D CD OC51 CALL auto select
OD50 C3 OBD2 JP _compute_file_size
;Disk anwählenJund höchste RecordJnummer bestimmen
229
ßDOS-Listing
• *>;<** 3DOS-Funktion Nummer 37 'Reset Disk1
> <** V t,
?reset disk:
OD53 2A 0343 LD
OD56OD57OD58
OD59OD5A
OD5BOD5E
OD5FOD60
OD61
OD62
OD63OD66OD67
OD6AOD6B
OD6COD6DOD6E
7D2F5F
1C2F
2 A ODAFA4
577D
A3
5F
2A ODADEB22 ODAF
7DA3
6F1CA2
LDCPLLD
LDCPL
LDAND
LDLD
AND
LD
LDEXLD
LDAND
LDLDAND
A, L.
E,A
A, H
HL, ( §login vec )11
D, AA, L
E
E, A
HL, ( §ro vec )DE , HL( §login_vec ) ,HL
A,LE
L, AA, HD
HL,(§entry_word) ; HL = Vektor; Die ge-;setzten Bitposi-;tionen werden im;Lgoin- und R/O-;Vektor gelöscht.
;Bits negieren;E - LSB der Vektor-;maske
;A - MSB der Vektor -;maske
;HL - Login-Vektor;Entsprechende Bits;löschen;und MSB in D merken;A = LSB des Login-;Vektors;Entsprechende Bits;löschen;und LSB in E merken
OD6F 67 LD H,A
HL = R/O-VektorDE und HL tauschenNeuen Login-Vektorspeichern und weiterals Maske benutzen(Es können nur Disks'R/O1 sein, die auchim Login-Vektorstehen)A = LSB der MaskeLSB des R/O-Vektorsmaskieren undin L speichernA = MSB der MaskeMSB des R/O-Vektorsmaskieren undin H speichern
OD70 22 ODAD LD (§ro_vec),HL
OD73 C9 RET
;Neuen R/O-Vektor;speichern
230
BDOS-Listing
; BDOS-Funktion abschliessen•i; Alle BDOS-Funktionen durchlaufen diese Routine
?bdos_exit:
OD74 3A ODDEOD77 B7OD78 CA OD91
OD7B 2A 0343OD7E 36 00
OD80 3A ODEOOD83 B7OD84 CA OD91
LDORJP
LDLD
LDORJP
A , ( §f ile_f unc? )AZ , ret_to_user
;Wurde eine File-Funk;tion ausgeführt ?;N: Fertig
HL,(§entry_word) ;HL -> FCB;Usernurnmer im FCB;löschen;War der Diskcode im;FCB gleich Null ?;J: Fertig, es wurde;keine neue Disk; selektiert
(HL),0
A,(§old_fcb_disk)AZ,ret_to_user
OD87 77 LD (HL), A
OD88OD8BOD8E
•/ret_to*/
OD91OD94
OD95OD98OD99OD9Ait• ****
?write
OD9BOD9EODAOODA3ODA5
ODA8ODAB
3A ODDF32 ODD6CD OC45
_user :
2A 030FF9
2A 03457D44C9
BDOS-F
LDLDCALL
LDLD
LDLDLDRET
unktion
A, ( §old__bdos_disk(§entry byte), A?select_disk
HL,(§user stack)SP,HL
HL,(§exit value)A, LB, H
Nummer 40 "Write
zero random:
CD OC513E 0232 ODD5OE 00CD OB07
CC OA03C9
CALLLDLDLDCALL
CALLRET
auto selectA, 2( § sequential? ) ,AC,0zero_trans__r_to_s
Z ,write_rnd_seq
;M: Alten Diskcode;wieder in den FCB^einsetzen;A - Alte Disknummer;Disknummer speichern;und alte Disk wiederjanwählen
;HL = StackpointerjAlten Stackpointer-jwert wieder einsetzenJHL = Rückgabewert
;und B »jFertig
H setzen
"Write Random with Zero Fill"
;Disk anwählen; Zugriffsflag ent-;sprechend setzen;Schreibkennung setzen;RRN in SRN wandelnjFehler ?;N: Record schreiben
231
BDOS-Listing
; Zweiter Parameterbereich
; 1-Byte FCB für 'Make File1
»- *. If * ',."» *•/•/
ODAC E5 §make fcb: defb Oe5h
; R/O-Vektor
ODAD 0000 §ro_vec: defw 0*
•
; Login-Vektor
ODAF 0000 §login_vec: defw 0
; DMA-Adresse für Schreib/Leseoperationen
ODB1 0080 ,„A§dma address: defw §buffer
r•r Zeiger auf die höchste belegte Eintragsnummer -»-1; (Zeiger nach DPH-f 2 )•
ODB3 0000 ?§last_entry: defw 0
r; Zeiger auf die aktuelle (logische) Spurnummer; (Zeiger nach DPH+4)•ODB5 0000 ?§track #: defw 0
; Zeiger auf die (logische) Recordnummer des ersten; Records im aktuellen (logischen) Track; (Zeiger nach DPH+6)£ v* ,
ODB7 0000 ?§trkrecord: defw 0
; Zeiger auf die Adresse des aktuellen Directory-; Buffers (DIRBUF) (= Inhalt von DPH+8)•
ODB9 0000 ?§dirbuf: defw 0
232
BDOS-Listing
; Zeiger auf die Adresse des aktuellen Disk-Parameter-; Blocks (DPB) (- Inhalt von DPH+10)•
ODBB 0000 ?§dpb: defw 0
r; Zeiger auf die Adresse des aktuellen Prüfsummen-; Vektors (CSV) (- Inhalt von DPH+12)•
ODBD 0000 ?§csv: defw 0
r
•r Zeiger auf die Adresse des aktuellen Belegungs-; Vektors (ALV) (° Inhalt von DPH + 14)/
»«-r. v,- ODBF 0000 ?§alv: defw 0
; Aktueller Disk Parameter Block (DPB)
§dpb:ODC1 0000 §spt: defw 0ODC3 00 §bsh: defb 0ODC4 00 §blm: defb 0ODC5 00 §exm: defb 0ODC6 0000 §dsm: defw 0ODC8 0000 §drm: defw 0ODCA 0000 §alO_a!1: defw 0ODCC 0000 §cks: defw 0ODCE 0000 §off: defw 0?r
»4»<«^ ; Zeiger auf die Adresse der aktuellen Sektor-Verschränkungs; Tabelle (XLTAB) (= Inhalt von DPH+0)
ODDO 0000 ?§xltab: defw 0•/r; Flag für 'open_next_extend"
; = FFH, falls beim Schliessen des alten Extends, auch der; komplette Eintrag geschlossen wurde.
ODD2 00 §entry_closed?: defb 0
233
BDOS-Listing
i•r Allgemeines Flag, ob zur Zeit eine Schreib- oder Lese-; funktion bearbeitet wird•r; = OOH, falls eine Schreibanforderung bearbeitet wire!; - FFH, falls eine Leseanforderung bearbeitet wird•ODD3 00 §readorwrite?: defb 0
; Fehlercode nach einer Directory-Suchfunktion•r; = OOH, falls ein passender Eintrag gefunden wurde; = FFH, falls kein passender Eintrag gefunden wurde•rODD4 00 §f ile_found?: defb 0•i•/; Zugriff skennung für die aktuelle Filefunktion•/; = 0, bei direktem (Random) Zugriff. = i f foei sequentiellem Zugriff; = 2, bei direktem Schreibzugriff mit Blockinitialisierung; (Write Random With Zero Fill)•
ODD5 00 §sequential?: defb 0•/«; 1 -Byte Eingangsparameter•
ODD6 00 §entry_byte: defb 0•t•t; Position der aktuelle Blocknummer in der Blocktabelle•iODD7 00 §block_pos: defb 0
; Anzahl der zu vergleichenden Bytes bei den Directory-; Suchfunktionen•tODD8 00 §compare count: defb 0
•r• Adresse des FCB, bei der Suche nach dem nächsten; passenden Eintrag•/ODD9 0000 ?§search fcb: defw 0
234
BDOS-Listing
r; Unbenutzt/ODDB oooo defw o•f•t; Flag, ob die Blocknummern als 8- oder 16 -Bit Wert in der; Blocktabelle abgelegt sind•f; - FFH, für 8-ßit Blocknummern; - OOH, für 16-Bit Blocknummern• "*/ODDD 00 §large_dsm?: defb 0
; Flag für ' ?bdos_exit ' , ob die abgeschlossene Funktion eine; Filefunktion war• <•/> -—•; =• FFH, für alle Filef uriktionen; = OOH sonst•
ODDE 00 §f ile__func?: defb 0•i• •9
• Alte Disknummer, falls für eine Filefunktion eine; andere Disk selektiert wurde•
ODDF 00 §old bdos disk: defb 0
; Im FCB übergebener Diskcode, der nach Beendigung der File-; funktion wieder eingesetzt wird•
ODEO 00 §oldfcbdisk: defb 0
; Höchste Recordnummer innerhalb des aktuellen Extends•/ODE1 00 §maxextrec: defb 0rt; Aktuelle Extendnummer
ODE2 00 §extend_#: defb 0•/•t; Aktuelle Recordnummer innerhalb des aktuellen Extends•/ODE3 0000 §sequ rec: defw 0
235
BDOS-Listing
; Blocknummer oder Absolute Recordnummer zur Anwahl eines; neuen Track und Sektors
§block_#:ODE5 0000 §abs_rec_#: defw 0J*; Absolute Recordnummer des ersten Records im aktuellen BlockrODE7 0000 §blkrecord: defw 0rr} Position des aktuellen Eintrags innerhalb des DIRBUF
ODE9 00 §dir_pos: defb 0•tr; Nummer des aktuellen Eintrags*
ODEA 0000 §dir entry #: defw 0
t•f Absolute Recordnummer des im DIRBUF stehenden Records
ODEC 0000 §dir record #: defw 0
; Bytes zum Auffüllen an die nächste Seitengrenze.; Damit braucht das BDOS genau 14 Seiten (OEOOH Bytes)
ODEE 00 defs 18,0•t•/; Start des BIOS•/bios :
END
236
Tips & Tricks
Tips &_ Tricks
Das CP/M Betriebsystem ist in mancher Hinsicht nicht geradeals 'benutzerfreundlich1 zu bezeichnen. Durch ein paar Än-derungen im CCP und im BDOS, kann das Verhalten des CP/Mjedoch in gewissen Grenzen verbessert v/erden.
Die nachfolgend beschriebenen Änderungen setzen Kenntnisse imProgrammieren in Maschinensprache bzw. Assembler voraus undv/enden sich vor allem an diejenigen, die ein eigenes 3IOSschreiben wollen.
Da sowohl im CCP als auch im BDOS noch Speicherplätze unbe-nutzt sind (14 Bytes am Ende des CCP, 18 Bytes am Ende desBDOS), können Programmteile auch dort untergebracht werden.Neue BIOS-Routinen v/erden am besten über eine Erv/eiterung derBlOS-Sprungleiste erreicht.
Alle Adressangaben sind in der Form CCP+xxxxH bzw. BDOS+xxxxKgemacht und bezeichnen dadurch immer eine relative Position,ausgehend vom Anfang des CCP bzw. des BDOS.
Submit von einem anderen Laufwerk
Submit-Files werden normalerweise vom CCP nur auf dem Lauf-werk A: erkannt.Das Programm 'SUBMIT.COM1 erzeugt das Submit-File '$$$.SUB'zwar auf dem jeweils aktuellen Laufwerk, der CCP wählt aberimmer das Laufwerk A: explizit an. Auch erkennt der CCP einenSUBMIT-Lauf nur dann, wenn die 'Reset Disk System'-Funktionim BDOS auf dem Laufwerk A:, einen mit '$' beginnenden File-namen findet.Durch drei Änderungen im CCP, wird ein Submit-File immer aufdem jeweils aktuellen Laufwerk erkannt:
Änderung von:in:
CCP+013DH CACCP+013DH 00CCP+013EH 00CCP+013FH 00
0196 JPNOPNOPNOP
Z,no_submit
damit wird immer versucht das File .SUB1 zu öffnen.
Änderung vonin:
CCP+0146HCCP+0146HCCP+0147HCCP+0148H
C4 OOBD000000
CALLNOPNOPNOP
NZ,select disk
damit wird die Anwahl vonFiles '$$i.SUB' verhindert.
Laufwerk A: vor dem Offnen des
237
Tips & Tricks
Änderung von: CCP+0181H C4 OOBD CALL NZ,select_diskin: CCP+0182H 00 NOP
CCP+0183H 00 NOPCCP+0184H 00 NOP
damit wird die Anwahl von Laufwerk A: vor dem Löschen desFiles 'iü.SUB1 verhindert.
Schliessen eines Files
Der in der CP/M Dokumentation angegebene Algorithmus zurBehandlung von physikalischen Sektoren mit mehr als 128 Bytes(Blocking and Deblocking), arbeitet nicht immer korrekt.Besonders beim Schliessen eines Files kann es passieren, daßder geänderte Directory-Sektor nicht zurückgeschrieben wird.Zur Behebung dieses Fehlers ist eine Erweiterung der BIOS-Sprungleiste um die Funktion 'Flush' (Internen Sektorbufferschreiben) nötig. Die 'Close File ' -Funktion im BDOS ist zudiesem Zweck f olgendermassen zu ändern:
-,•*-.--;•<„ ...... Änderung von BDOS + OCA8K C3 08A2 JP _close_filein: BDOS+OCA8H C3 xxxx JP flush
Die Routine 'flush1 muß als ersten Befehl einen 'CALLBDOS+08A2H1 enthalten, der die 'Close File ' -Funktion aus-führt. Danach muß der BIOS-interne Sektorbuffer auf die Disk-ette geschrieben und die Routine mit einem 'RET1 beendetwerden.
Ausgabe der Usernummer
Beim Arbeiten in verschiedenen Userbereichen ist es oft sehtstörend, daß das CP/M keine Angaben über die aktuelle User-nurnmer macht. Durch Änderung der 'Set/Get User Code ' -Funktionira BDOS kann eine neue Usernummer erkannt und über einespezielle BIOS-Funktion (hier 'show_user' genannt) darge-stellt v/erden.
Änderung von: BDOS+OD3DH 32 0341 LD (§user_#),Ain: BDOS+OD3DH CD xxxx CALL show_user
Die ' show_user ' -Funktion muß die im A-Register übergebeneUsernummer in BDOS+0341H ablegen. Die Anzeige kann entwederdurch einen speziellen Tastencode (z.B. im Zusammenhang mitder BIOS-Funktion 'CONIN1) oder über eine zusätzliche Bild-schirmzeile (falls vorhanden) erfolgen.
Anzeige der Printfunktion
Der aktuelle Status der über CTRL-P schaltbaren Drucker-Protokollfunktion im BDOS, kann durch folgende Änderung dem
238
Tips & Tricks
BIOS (hier 'show_print' genannt) mitgeteilt werden:
Änderung von: BDOS^0245H C3 01EF JPin: ' BDOS+0245K C3 xxxx JP
read_next1show_print
Die BIOS-Funktion darf keines der Register verändern. DasRegister A enthält eine 1 , falls die Protokollfunktion einge-schaltet wurde, sonst 0.
Andere Fehlermeldungen
Die Fehlerroutinen im 3DOS werden alle über die 'err_loc__table1 an der Adresse BDOS+0009H erreicht. Durch Ersetzendieser Tabelle, kann die Fehlerbehandlung auch im BIOS durch-geführt v/erden. Eine weiter Möglichkeit ist auch, die Ver-weise auf die Fehlertexte in den BDOS-Fehlerroutinen zu än-dern:
Änderung von: BDOS+0099H 21 OOCAin: BDOS+0099H 21 xxxx
für den 'Bad Sector'-Fehler.
Änderung von: BDOS+OOA5Hin: BDOS+OOA5H
für den 'Select'-Fehler.
21 OOD521 xxxx
Änderung von: BDOS+OOABH 21 OOE1in: BDOS+OOABH 21 xxxx
für den 'Disk R/O1-Fehler.
Änderung von: BDOS+OOB1H 21 OODCin: BDOS+OOB1H 21 xxxx
für den 'R/O'-Fehler.
LD HL,txt_bad_sectorLD HL,xxxx
LD HL,txt_selectLD HL,xxxx
LD HL,txt_disk_roLD HL,xxxx
LD HL,txt_file_roLD HL,xxxx
Die neuen Fehlertext müssen entsprechend dem CP/M-Standard,mit '$' abgeschlossen sein.
Warmstart nach einem Schreib/Lesefehler
Nach einem 'Bad Sector ' -Fehler kann die fehlerhafte Funktionentweder wiederholt oder durch einen Warmstart abgebrochenwerden. Im letzteren Fall greift der CCP wieder auf daszuletzt angewählte Laufwerk zu.Lag nun der gemeldete Fehler im Directory-Bereich der Disk-ette, so tritt er beim 'Einloggen' der Diskette wieder aufund ein Abbruch ist nur noch durch Ausschalten des Rechnersmöglich.Durch die folgende Änderung kann das Verhalten nach einem
239
Tips & Tricks
"Bad Sector'-Fehler geändert werden:
Änderung von:in:
BDOS+OOA1HBDOS+OOA1H
CA 0000CA xxxx
JP Z,?bootJP Z,err wboot
Die Routine err_wboot kann z.B. den Wert der Speicherstelle0004H ändern und dadurch die Anwahl eines anderen Laufwerkeserreichen.
Warmstart nach einem 'Select'-Fehler
Der CCP ändert vor der Anwahl eines neuen Laufwerkes immererst die Speicherzelle 0004H. Prüft das BIOS vor dem Startdes CCP nicht den Inhalt dieser Speicherzelle, sondern über-gibt ihn einfach im C-Register, so führt dies zu einem er-neuten 'Select'-Fehler.Die weiter oben genannte 'err_wboot'-Routine kann auch indiesem Fall benutzt werden:
Änderung vonin: _,._,.„ , ,.,.,
BDOS+OOB7HBDOS+OOB7H
C3 0000 JPC3 xxxx JP
?booterr wboot
Durch diese Änderung wird allerdings auch nach einemR/O1- oder 'R/O'-Fehler ein neues Laufwerk angewählt.
'Disk
240
Labels
Alphabetische Reihenfolge der CCP-Label
7BDOS?BUFFER_ADRESS?DEFAULT_FCB?DISK_BUFFER?FIRST_CHAR?TPA_START§CURRENT_DEFAULT _DRIVEADD_HL_ABACKBAD_LOADBDOSBDOS_CALLBDOS_DISKIOBELLBUFFERB_CLOSE_FILEB_CONSOLE_INPUTB_CONSOLE_OUTPUTB_CONSOLE_STATUSB_DELETE_FILEB_MAKE_FILEB_OPEN_FILEB_READ_BUFFERB_READ_SEQUB_RENAME_FILEB_RESET_DRIVEB_RESET_SYSTEMB_RETURN__CURRENTB_RETURN_DISKB_SEARCH_FIRSTB__SEARCH_NEXTB_SELECT_DISKB_SET_DMAB_SET_GET_USERB_WRITE_SEQUCCPCCP_PROMPTCHECK_CONSOLECHECK_WILDCARDCLEAR_REC_NOCLEAR_REC_NO_LOOPCLOSE_FILECLOSE_SAVE_FILECMD_ADRESSESCMD_TABLECOMMAND_ERRORCOMPARE_LOOPCOMPARE_NEXT_CHARCOMPARE_NEXT_CMDCOMPARE_SERIALCONOUTCONOUT BC
0005H0088H005CH0080H008AH0100H0004H0259H0008H0771H0800HOOC3HOOF4H0007H0006H0010H0001H0002HOOOBH001 3H001 6HOOOFHOOOAH001 4H001 7H0025HOOODH001 9H0018H0011H0012HOOOEH001 AH0020H001 5HOOOOH0382H01C2H0301H02FOH02F2HOODAH05F1H03C1H0310H0209H01FDH033CH0333H01F5H008CH0092H
241
Labels
CONVERT_LOOPCRCTRLPCURRENT_DISKCURRENT_SUBMIT_RECDEFAULT_EXTDELDELETE_FILEDELETE_SUBMITDIRDIR_EXITDIR_FILEDIR_LOOPDIR_NEXT_CHARDIR_NEXT_IN_LINEDIR_PRINT_CHARDIR_PRINT_SPACEENTRY_NOT_USEDEOFERAERA_SINGLE_FILEEXECUTE_CMDEXECUTE_PROGRAMFILE_DRIVE_NOFILE_EXISTSFILL_EXT_SPACEFILL_FCB_SPACEGET_BYTE_FROM_BUFFERGET_CHECK_CKARGET_COMMAND_LINEGET_DRIVE_CODEGET_NEXT_CHARGET_NEXT_DIR_ENTRYGET_NUMBERGET_NUMBER_EXITGET_NUMBER_LOOPGET_USERINC_CMD_COUNTERINC_TO_NEXT_CMDINTERNAL_EXTENSIONINTERNAL_FCBINTERNAL_FILENAMEINTERNAL_RECORD_#LFLOAD_AND_EXECUTELOAD_NEXT_RECORDMAKE_FILEMAKE_UPPERMOVE_3_BYTESMOVE_B_BYTESNEXT_EXTENSION_CHARNEXT_FILENAME_CHARNO_FILENO NEW DRIVE
01ABHOOODH0010H07EFH07CCH0783H007FHOOEFH01DDH0477H051BH048FH0498H04D9H04CCH04F9H04F7H050FH001AH051FH0542H0398H06A5H07FOH0679H02E9H02B9H044BH0230H0139H01DOH024FH050EH03F8H0433H0408H0113H0354H034FH07D6H07CDH07CEH07EDHOOOAH06C4K06E1H0109H0130H0440H0442H02DBH02ABH03EAH0289H
242
Labels
NO_SPACENO_SUBMITNO_WILDCARDOPEN_FCBOPEN_FILEPRINT_CRLFPRINT_LOOPPRINT_NEXT_CHARPRINT_QUESTION_MARKPRINT_SPACEPRINT_TEXTPROMPTREAD_ERRORREAD_FCBREAD_SEQUREENTER_CCPREENTER_NEW_DISKRENRENAME_FCBRENAME_FILEREN_DELIMITER_OKREN_DISK_OKREN_FILE_NOT_FOUNDREN_NO_FILERESET_BUFFERRESET_DISKRETURN_CODERUN_TRANSIENTSAVESAVE_EXITSAVE_LOOPSEARCH_CCP_CMDSEARCH_END_OF_EXTENSIONSEARCH_END_OF_FILENAMESEARCH_FCBSEARCH_FIRSTSEARCH_NEXTSEARCH_PARAMETERSSELECT_DISKSELECT_NEW_DISKSELECT_OLD_DISKSERIAL_NUMBERSETUP_CMD_BUFFERSETUP_CMD_BUFFER_LOOPSETUP_EXTENSIONSETUP_EXTENSION_LOOPSETUP_FCBSETUP_FCB_OFFSETSETUP_FILENAMESETUP_FILENAME_LOOPSETUP_PARAMETERSSET_CHAR_TO_EXTSET_CHAR_TO_FCBSET COMMAND
05FBH01 96H0309HOODOHOOCBH0098HOOACH020FH0222HOOA2HOOA7H003EH03D9HOOFEHOOF9H0786H0789H0610H07DDH01 OEH063FH0659H0673H066DH01 BAHOOB8H07EEH074FH05ADH0601H05D4H032EH02DFH02AFHOOE9HOODFHOOE4H0730HOOBDH0454H0466H0328H073EH0743H02COH02C8H025EH0260H0296H0298H0701H02D9H02A9H01A7H
243
Labels
K"... •. f*j< vjt V» .t -C!
SET_DEFAULT_DMASET_DMASET_DRIVESET_DRV_USRSET_NEW_DRIVESET_USERSET_WILDCARD_LOOPSHOW_FILESPACESTACK_AREASTART_DRIVE_CS TART_NO_COMMAN DSUBMIT_FCBSUBMIT_FLAGSUBMIT_REC_COUNTSUBMIT_REC_NOTABTRANSIENT_NOT_FOUNDTXT_ALL_YNTXT_BAD_LOADTXT_FILE_EXISTSTXT_NO_FILETXT_NO_SPACETXT_READ_ERRORTYPETYPE_CHARTYPE_CHAR_COUNTERTYPE_ERRORTYPE_EXITTYPE_LOOPUSERWRITE_SEQUWRONG SERIAL
01D5H01D8H0129H01 1AH0290H0115H0488H04D4H0020H07ABH035CH0358H07ACH07ABH07BBH07BAH0009H076BH0552H077AH0682H03FOH0607H03DFH055DH0587H07F1H05A7H05AOH0574H068EH0104H03CFH
244
Labels
Numerische Reihenfolge der CCP-Label
OOOOH0001H0002H0004H0005H0006H0007H0008H0009HOOOAHOOOAHOOOBHOOODHOOODHOOOEHOOOFH0010H0010H0011H0012H0013H0014H0015H0016H0017H0018H0019H001AH001AH0020H0020H0025H003EH005CH007FH0080H0088H008AH008CH0092H0098HOOA2HOOA7H00 ACHOOB8HOOBDHOOC3HOOCBHOODOHOODAHOODFHOOE4H
CCPB_CONSOLE_1NPUTB_CONSOLE_OuTPUT§CURRENT_DEFAULT_DRIVE7BDOSBUFFERBELLBACKTABB_READ_BUFFERI.FB_CONSOLE_STATUSB_RESET_SYSTEMCRB_SELECT_DISKB_OPEN_FILEB_CLOSE_FILECTRLPB_SEARCH_FIRSTB_SEARCH_NEXTB_DELETE_FILEB_READ_SEQUB_WRITE_SEQUB_MAKE_FILEB_RENAME_FILEB_RETURN_DISKB_RETURN_CURRENTB_SET_DMAEOFB_SET_GET_USERSPACEB_RESET_DRIVEPROMPT?DEFAULT_FCBDEL?DISK__BUFFER?BUFFER_ADRESS?FIRST_CHARCONOUTCONOUT_BCPRINT_CRLFPRINT_SPACEPRINTJTEXTPRINT__LOOPRESET_DISKSELECT_DISKBDOS_CALLOPEN_FILEOPEN_FCBCLOSE_FILESEARCH_FIRSTSEARCH NEXT
245
Labels
' i.« "i;*«"* '- - >"
OOE9HOOEFHOOF4HOOF9HOOFEH0100H0104H0109H01 OEH01 1 3H01 15H011AH0129H0130H01 39H0196H01A7H01ABH01 BAH01C2H01DOH01D5H01D8H01 DDK01F5H01FDH0209H020FH0222H0230H024FH0259H025EH0260K0289H0290H0296H0298H02A9H02ABH02AFH02B9H02COH02C8H02D9H02DBH02DFH02E9H02FOH02F2H0301H0309H0310H0328H
SEARCH_FCBDELETE_FILEBDOS_DISKIOREAD_SEQUREAD_FCB?TPA_STARTWRITE_SEQUMAKE_FILERENAME_FILEGET_USERSET_USERSET_DRV_USRSET_DRIVEiMAKE_UPPERGET_COMMAND_LINENO_SUBMITSET_COMMANDCONVERT_LOOPRESET_BUFFERCHECK_CONSOLEGET_DRIVE_CODESET_DEFAULT_DMASET_DMADELETE_SUBMITCOMPARE_SERIALCOMPARE_LOOPCOMMAND_ERRORPRINT_NEXT_CHARPRINT_QUESTION_MARKGET_CHECK_CHARGET_NEXT_CHARADD_HL_ASETUP_FCBSETUP_FCB_OFFSETNO_NEW_DRIVESET_NEW_DRIVESETUP_FILENAMESETUP_JFILENAME_LOOPSET_CHAR_TO_FCBNEXT_FILENAME_CHARSEARCH_END_OF_FILENAMEFILL_FCB_SPACESETUP_EXTENSIONSETUP_EXTENSION_LOOPSET_CHAR_TO_EXTNEXT_EXTENSION_CHARSEARCH_END_OF_EXTENSIONFILL_EXT_SPACECLEAR_REC_NOCLEAR_REC_NO_LOOPCHECK_WILDCARDNO_WILDCARDCMD_TABLESERIAL NUMBER
246
032EH0333H033CH034FH0354H0358H035CH0382H0398H03C1H03CFH03D9H03DFH03EAH03FOH03F8H0408H0433H0440H0442H044BH0454H0466H0477H0488H048FH0498H04CCH04D4H04D9H04F7H04F9H050EH050FH051BH051FH0542H0552H055DH0574H0587H05AOH05A7H05ADH05D4H05F1H05FBH0601H0607H0610H063FH0659H066DH0673H
Labels
SEARCH_CCP_CMDCOMPARE_NEXT_CMDCOMPARE_NEXT_CHARINC_TO_NEXT_CMDINC_CMD_COUNTERSTART_NO_COMMANDSTART_DRIVE_CCCP_PROMPTEXECUTE_CMDCMD_ADRESSESWRONG_SERIALREAD_ERRORTXT_READ_ERRORNO_FILETXT_NO_FILEGET_NUMBERGET_NUMBER_LOOPGET_NUMBER_EXITMOVE_3_BYTESMOVE_B_BYTESGET_BYTE_FROM_BUFFERSELECT_NEW_DISKSELECT_OLD_DISKDIRSET_WILDCARD_LOOPDIR_FILEDIR_LOOPDIR _NEXT_IN_LINESHOW_FILEDIR_NEXT_CHARDIR_PRINT_SPACEDIR_PRINT_CHARGET_NEXT_DIR_ENTRYENTRY_NOT_USEDDIR_EXITERAERA_SINGLE_FILETXT_ALL_YNTYPETYPE_LOOPTYPE_CHARTYPE_EXITTYPE_ERRORSAVESAVE_LOOPCLOSE_SAVE_FILENO_SPACESAVE_EXITTXT_NO_SPACERENREN_DELIMITER_OKREN_DISK_OKREN_NO_FILEREN FILE NOT FOUND
247
Labels
0679H0682H068EH06A5H06C4H06E1H0701H0730H073EH0743H074FH076BH0771H077AH0783H0786H0789H07ABH07ABH07 ACH07 BAH07BBH07CCH07CDH07CEH07D6H07DDH07EDH07EEH07EFH07FOH07F1H0800H
FILE_EXISTSTXT_FILE_EXISTSUSEREXECUTE_PROGRAMLOAD_AND_EXECUTELOAD_NEXT_RECORDSETUP_PARAMETERSSEARCH_PARAMETERSSETUP_CMD_BUFFERSETUP_CMD_BUFFER_LOOPRUN_TRANSIENTTRANSIENT_NOT_FOUNDBAD_LOADTXT_BAD_LOADDEFAULT_EXTREENTER_CCPREENTER_NEW_DISKSTACK_AREASUBMIT_FLAGSUBMIT_FCBSUBMIT_REC_NOSUBMIT_REC_COUNTCURRENT_SUBMIT_RECINTERNAL_FCBINTERNAL_FILENAMEINTERNAL_EXTENSIONRENAME_FCBINTERNAL_RECORD_#RETURN_CODECURRENT_DISKFILE_DRIVE_NOTYPE_CHAR_COUNTERBDOS
248
Labels
Alphabetische Reihenfolge der BDOS-Label
_CLOSE_FILE_COMPUTE_FILE_SIZE_MAKE_FILE_OPEN_FILE-_READ_RANDOM_READ_SEQU_RENAME_FILE_SET_FILE_ATTR_WRITE_RANDOM_WRITE_SEQU?§ALV?§CSV?§DIRBUF?§DPB?§END_OF_ENTRIES?§SEARCH_FCB?§TRACK_#? §TRACK_RECORD_#?§XLTAB?BDOS_EXIT7BOOT?CLOSE_FILE?COMPUTE_FILE_SIZE?CONSOLE_INPUT?CONSOLE_OUTPUT?DELETE_FILE?DIRECT_IOPDUMMY?ERR_BAD_SECTOR?ERR_DISK_RO?ERR_FILE_RO?ERR_SELECT?GET_ALLOCATION_ADDR?GET_CONSOLE_STATUS?GET_IO_BYTE?GET_PARAMETER_ADDR?GET_RO_VEC?MAKE_FILE?OPEN_FILE?PRINT_STRING?READER_INPUT?READ_CONSOLE_BUFFER?READ_RANDOM?READ_SEQU?RENAME_FILE?RESET_DISK?RESET_DISK_SYSTEM?RETURN_CURRENT_DISK?RETURN_LOGIN_VEC?RETURN_VERSION_#?SEARCH_FIRST7SEARCH NEXT
08A2HOBD2H0924H0851HOB93H09BCH0816H083BHOB9CH09FEHODBFHODBDHODB9HODBBHODB3HODD9HODB5HODB7HODDOHOD74HOOOOHOCA5HOD4DH02C8H0190HOCD7H02D4H0304H0099HOOABHOOB1HOOA5HOD1 1H02FEH02EDHOD26HOD1 7HOCECHOC9CH02F8H02CEH01E1HOD41HOCEOHOCF5HOD53HOC83HOD04HOCFEHOC7EHOCABHOCC8H
249
Labels
?SELECT_DISK?SET_DMA?SET_FILE_ATTR? S ET_GET_U S ER_CODE?SET_IO_BYTE?SET_RANDOM_RECORD?WRITE_PROTECT_DISK?WRITE_RANDOM?V7RITE_SEQU?WRITE_ZERO_RANDOM§ABSOLUTE_RECORD_#§ALO_AL1§AUTO_SELECTED?§BDOS_DMA_ADDRESS§BLM§BLOCK_#§BLOCK_OFFSET§BLOCK_START_RECORD§BSH§CHARS_IN_LINE§CKS§COMPARE_COUNT§CURRENT_DISK§CURRENT_EXTEND_#§CURRENT_SEQU_REC§DEFAULT_DISK§DIR_ENTRY_#§DIR_OFFSET§DIR_RECORD_#§DISK_BYTE§DISK_NAME§DRM§DSM§ENTRY_BYTE§ENTRY_CLOSED?§ENTRY_WORD§EXIT_VALUE§EXM§EXT_RECORD_COUNT§FCB_DISK_#§FILE_FOUND?§INPUT_START§IO_BYTE§LARGE_DSM?§LOGIN_VEC§MAKE_FCB§OFF§OUTPUT_COUNTER§PRINT_FLAG§READ_OR_WRITE?§RO_VEC§SEQUENTIAL?§SPT§STATUS CHAR
OC45HODOAHOD1DHOD2DH02F3HOCOEH052CHOD47HOCE6HOD9BHODE5HODCAHODDEHODB1HODC4HODE5HODD7HODE7HODC3H030AHODCCHODD8H0342HODE2HODE3HODDFHODEAHODE9HODECH0004HOOC6HODC8HODC6HODD6HODD2H0343H0345HODC5HODE1HODEOHODD4H030BH0003HODDDHODAFHODACHODCEH030CH030DHODD3HODADHODD5HODC1H030EH
250
Labels
§USER_#§USER_STACKADD_A_BADD_HL_AADJUST_TABALLOCATE_BLOCKALLOCATE_HIGHERALLOCATE_LOWERALLOCATE_NEXT_BLOCKALLOCATE_NEXT_LOOPALL_ENTRIES_COMPARED ?AUTO_SELECTBACKBACKJTABBAD_RND_ACCESSBAD_SECTOR_ERRORBDOS - -BDOS1BDOS_LOC_TABLEBELLBIOSBLOCK_1_LOOP ' •BLOCK_2_LOOPBLOCK_WR I TE__LOOPBLOCK_WRITE_NEWBLOCK_WRITE_NORMALBYTE_BLOCK_CLOSEB_CBOOTB_CONINB_CONOUTB_CONSTB_HOMEB_LISTB_LISTST ., , , ..B_PUNCHB_READB_READERB_SECTRNB_SELDSKB_SETDMAB_SETSECB_SETTRKB_WBOOTB_WRITECANT_CLOSECANT_EXTEND_FILECHANGE_ALV_BITCHAR_XOFF?CHECKSUM_DIRBUFCHECKSUM_LOOPCHECK_§BLOCK_#CHECK_CHARCHECK_CTRLECHECK CTRLP
0341H030FH045CH0564H0162H07ECH07D1H07F4H07BEH07 CO H05F5HOC51H0008H0299HOB84H03BDH0006H001 1 H0047H0007HOEOOH044 5 H0453HOA9AHOA6CHOA6EH08D4HOEOOHOE09HOEOCHOE06HOE18HOEOFHOE2DHOE12HOE27HOE1 5HOE30HOE1BHOE24HOE21HOE1EHOE03HOE2AH091FH09B6H065CH01 23H04F7H04FDH0484H01 1 4H0226H0237H
251
Labels
CHECK_CTRLRCHECK_CTRLUCHECK_CTRLXCHECK_DELCHECK_DIR_OFFSETCHECK_DIR_RECORDCHECK_DISK_ROCHECK_EXTEND_#CLEAR_EXIT_VALUECLEAR_LINECLEAR_LOOPCLOSE_BLOCK_LOOPCLOSE_BYTE_BLOCKCLOSE_NEXT_BLOCKCLOSE_WORD_BLOCKCLR_ALV_LOOPCOMPAREJEXTENDCOMPARE_NEXT_CHARCOMPARE_NEXT_LOOPCOMPUTE_SIZE_LOOPCORRECT_RND_ACCESSCRCTRLCCTRLECTRLPCTRLRCTRLUCTRLXCTRLX_LOOPDEFAULT_DMADELDELETE_TABSDIFFERENT_EXTENDDIRECT_CONINDIR_OFFSET_LOOPDIR_READDIR_WRITEDISK_FULLDISK_RO?' DISK_RO_ERROREND_OF_FILEEND_OF_INPUTENTRY_#_FREE?ENTRY_FOUNDENTRY_NOT_FOUNDENTRY_NOT_RIGHTENTRY_RO?ERASE_FILESERASE_LOOPERROR_ENTRYERROR_TEXTERR_BOOTERR_LOC_TABLEFCB RO?
026BH025FH0248H021 6H0619H0605H051 EH0707HOAFEH01B1H01B9H08CDH08DBH08FDH0894H06B1H0773H077CH0753HOBE4HOB7FHOOODH0003H0005H0010H0012H0015H0018H024EH0080H007FH028AHOB47H02EOH0620H05D4H05C6HOA43H0554H0558H09FBH02C1H057FH09 ACH0794H06F6H0544H079CH07A4H034AH00 BAHOOB4H0009H0547H
252
Labels
FILE_RO_ERRORGET_ALV_BITGET_ALV_LOOPGET_BLOCK_#GET_BLOCK_OFFSETGET_BLOCK_WORDGET_CHARGET_ENTRY_POINTERGET_EXTEND_POINTERGET_RC_CR_POINTERGET_RECORD__#SGET_S2HOME_DISKINPUT_CHARJP_UPDATE_RECORD_#SLFLOGICAL_SELECTLOGIN_CURRENT_DISKLOGIN_NEXT_ENTRYMAKE_CLEAR_LOOPMAX_FUNC_#MOVE_DE_HLMOVE_DIRBUF_TO_DMAMOVE_LOOPNEW_BLOCK_WORDNEW_END_OF_ENTRIES?NEW_EXTEND_OPENEDNEW_EXT_TOO_BIGNOT_BACKNOT_CTRLCNOT_GREATERNO_AUTO_SLCTNO_BLOCK_ALLOCPOS_CRPOS_DXPOS_EXPOS_ROPOS_ROPOS_RCDIFF_RC_CRPOS_S1POS_EGOPEN_ENTRYOPEN_NEXT_EXTENDPHYSICAL_SELECTPOP_HLPRINT_BACKPRINT_BACKSPACEPRINT_CHARPRINT_CR_LFPRINT_TEXTREAD_NEXT1READ_NEXT2READ NEXT RECORD
054EH0635H0656H045EH043EH0471HOOFBH055EH04A6H04AEH04BBH0569H03A1H0106HOBOOHOOOAH06A3HOC21H06D2H0946H0029H034FH05E9H0350HOA64H058CH09AFH0983H0179H02BDHOC06HOC75H069DH0020H0010HOOOCH0009H0021HOOOFH001 1HOOODHOOOEH085AH095AH0359HOCOCH01 ACH01 A4H0148H01C9H01D3H01EFH01F1H09E6H
253
Labels
READ_RECORDREAD_RND_SEQREAD_WRITE_ERRORREC_OFFSET_LOOPRENAME_LOOPRESET_ENTRY_#RESTORE_DMARETURN_BYTERETURN_DIR_CODERETURN_FOUND_FLAGRETURN_WORDRETYPE_LINERETYPE_LOOPRET_TO_USERRND_SEEK_ERRORSAME_BYTE_BLOCK?SAVE_CHARSAVE_STATUSSEARCH_DIR_FIRSTSEARCH_DIR_NEXTSEARCH_MAKESEARCH_NEXT_EXTENDSEARCH_NOWSELECT_ERRORSELECT_NEW_OKSERIAL_#SET_§ABSOLUTE_RECORD#SET_§BLOCK_#SET_ALV_LOOPSET_ATTR_LOOPSET_DIR_TRK_SECSET_DISK_VECSET_DMA_TO_DIRBUFS ET_DMA__TO_HLSET_DSK_TRK_SECSET_RECORD_COUNTSET_S2SET_USER_CODESHIFT_LEFT_HLSHIFT_LEFT_LOOPSHIFT_RIGHT_HLSHIFT_RIGHT_LOOPSHOW_CHARSHOW_ERRORSHOW_INPUTSHOW_TABSPACESTACKSTILL_IN_CURRENT_EXTSUB_DE_HLTABTEST_BLOCK_#TEST_CSVTEST RW STATUS
03B2H09C1H0305H0490H0827H05FEH05DAH0301H0783H0701HOD29H0270H0278HOD91HOB8BH08E1H02A6H0142H0718H072DH074AH098EHOCC2H0347H039DHOOOOH048AH0477H0664H0840H03C3H050BH05EOH05E3H03D1H088BH0578HOD3BH0504H0505H04EAH04EBH017FHOOE5H02A9H01 96H0020H0341HOAD2H0595H0009H068EH059EH03BBH
254
Labels
TRACK_DECTRACK_FOUNDTRACK_INCTRANS_SEQ_TO_RNDTRNS_RND_TO__SEQTRUE_STATUSTXT_BAD_SECTORTXT_DISK_ROTXT_FILE_ROTXT_SELECTUPDATE_ALVUPDATE_ALV_LOOPUPDATE_CSVUPDATE_CSV_BYTEUPDATE_RECORD_#SUPDATE_SEQU_#VERSION_#WORD_BLOCK_CLOSEWORD_VALUEWRITE_ACTUAL_DATAWRITE_CLOSED_ENTRYWRITE_COMPLETE_ENTRYWRITE_DIR_RECORDWRITE_NEW_BLOCKWRITE_NEW_ENTRYWRITE_PARTIAL_ENTRYWRITE_RECORDWRITE_RND_SEQXOFFXONZERO_S2Z ERO_TR ANS_R_TO_SZERO WRITE BUFFER
03E4H040FH03FAHOBA5HOB03H01 45HOOCAHOOE1HOODCHOOD5H066BH0675H059CH05C4H04D2H04DEH0022H08E8H0688HOABBH091 7H07FDH0810HOA48HOA3BH0801H03B8HOA03H0013H001 1H0572HOB07HOA8CH
255
Labels
Numerische Reihenfolge der BDOS-Label
OOOOHOOOOH0003H0003H0004H0005H0006H0007H0008H0009H0009H0009HOOOAHOOOCHOOODHOOODHOOOEHOOOFH0010H0010H0011H0011H0011H0012H0013H0015H0018H0020H0020H0021H0022H0029H0047H007FH0080H0099HOOA5HOOABHOOB1HOOB4H00 BAHOOC6HOOCAHOOD5HOODCHOOE1HOOE5HOOFBH0106H01 14H0123H01 42H
7BOOTSERIAL_#§IO_BYTECTRLC§DISK_BYTECTRLEBDOSBELLBACKERR_LOC_TABLEPOS_ROTAB !LF !POS_EXCR lPOS_S1 !POS_EGPOS_RCCTRLPPOS_DXBDOS1DIFF_RC_CR !
XONCTRLRXOFFCTRLU !CTRLX ;POS_CR !SPACE iPOS_ROVERSION_#MAX_FUNC_#BDOS_LOC_TABLEDELDEFAULT_DMA?ERR_BAD_SECTOR?ERR_SELECT?ERR_DISK_RO?ERR_FILE_ROERR_BOOTERRORJTEXT§DISK_NAMETXT_BAD_SECTORTXT_SELECTTXT_FILE_ROTXT_DISK_ROSHOW_ERRORGET_CHARINPUT_CHARCHECK_CHARCHAR_XOFF?SAVE STATUS
256
Labels
01 45H0148H01 62H0179H017FH01 90H0196H01A4H01 ACH01B1H01B9H01C9H01D3H01E1H01EFH01F1H021 6H0226H0237H0248H024EH025FH026BH0270H0278H028AH0299H02A6H02A9H02BDH02C1H02C8H02 GEH02D4H02EOH02EDH02F3H02F8H02FEH0301H0304H0305H030AH030BH030CH030DH030EH030FH0341H0341H0342H0343H0345H0347H
TRUE_STATUSPRINT_CHARADJUST_TABNOT_BACKSHOW_CHAR?CONSOLE_OUTPUTSHOW_TABPRINT_BACKS PACEPRINT_BACKCLEARJLINECLEAR_LOOPPRINT_CR_LFPRINT_TEXT l?READ_CONSOLE_BUFFERREAD_NEXT1 jREAD_NEXT2CHECK_DELCHECK_CTRLECHECK_CTRLPCHECK_CTRLXCTRLX_LOOPCHECK_CTRLUCHECK_CTRLRRETYPE_LINERETYPE_LOOPDELETE_TABSBACK_TABSAVE_CHARSHOW_INPUTNOT_CTRLCEND_OF_INPUT?CONSOLE_INPUT?READER_INPUT?DIRECT_IODIRECT_CONIN?GET_IO_BYTE?SET_IO_BYTE?PRINT_STRING?GET_CONSOLE_STATUSRETURN_BYTE7DUMMYREAD_WRITE_ERROR§CHARS_IN_LINE§INPUT_START§OUTPUT_COUNTER§PRINT_FLAG§STATUS_CHAR§USER_STACK§USER_#STACK§CURRENT_DISK§ENTRY_WORD§EXIT_VALUESELECT ERROR
257
Labels
034AH034FH0350H0359H039DH03A1H03B2H03B8H03BBH03BDH03C3H03D1H03E4H03FAH040FH043EH0445H0453H045CH045EH0471H0477H0484H048AH0490H04A6H04AEH04BBH04D2H04DEH04EAH04EBH04F7H04FDH0504H0505H050BH051EH052CH0544H0547H054EH0554H0558H055EH0564H0569H0572H0578H057FH058CH0595H059CH059EH
ERROR_ENTRYMOVE_DE_HLMOVE_LOOPPHYSICAL_SELECTSELECT_NEW_OKHOME_DISKREAD_RECORDWRITE_RECORDTEST_RW_STATUSBAD_SECTOR_ERRORSET_DIR_TRK_SECSET_DSK_TRK_SECTRACK_DECTRACK_INCTRACK_FOUNDGET_BLOCK_OFFSETBLOCK_1_LOOPBLOCK_2_LOOPADD_A_BGET_BLOCK_#GET_BLOCK_WORDSET_§BLOCK_#CHECK_§BLOCK_#SET_§ABSOLUTE_RECORD#REC_OFFSET_LOOPGET_EXTEND_POINTERGET_RC_CR_POINTERGET_RECORD_#SUPDATE_RECORD_#SUPDATE_SEQU_#SHIFT_RIGHT_HLSHIFT_RIGHT_LOOPCHECKSUM_DIRBUFCHECKSUM_LOOPSHIFT_LEFT_HLSHIFT_LEFT_LOOPSET_DISK_VECCHECK_DISK_RO I?WRITE_PROTECT_DISKENTRY_RO?FCB_RO?FILE_RO_ERRORDISK_RO?DISK_RO_ERRORGET_ENTRY_POINTERADD_HL_AGET_S2ZERO_S2SET_S2ENTRY_#_FREE?NEW_END_OF_ENTRIES?SUB_DE_HLUPDATE_CSVTEST CSV
258
05C4H05C6H05D4H05DAH05EOH05E3H05E9H05F5H05FEH0605H061 9H0620H0635H0656H065CH0664H066BH0675H0688H068EH069DH06A3H06B1H06D2H06F6H0701H0707H0718H072DH074AH0753H0773H077CH0783H0794H079CH07A4H07BEH07COH07D1H07ECH07F4H07FDH0801H0810H0816H0827H083BH0840H0851H08 SAH088BH0894H08A2H
Labels
UPDATE_CSV_BYTEDIR_WRITEDIR_READRESTORE_DMASET_DMA_TO_DIRBUFSET_DMA_TO_HLMOVE_DIRBUF_TO_DMAALL_ENTRIES_COMPARED?RESET_ENTRY_#CHECK_DIR_RECORDCHECK_DIR_OFFSETDIR_OFFSET_LOOPGET_ALV_BITGET_ALV_LOOPCHANGE_ALV_BITSET_ALV_LOOPUPDATE_ALVUPDATE _ALV_LOOPWORD_VALUETEST_BLOCK_#NO_BLOCK_ALLOCLOGICAL_SELECTCLR_ALV_LOOPLOGIN_NEXT_ENTRYENTRY_NOT_RIGHTRETURN_FOUND_FLAGCHECK_EXTEND_#SEARCH_DIR_FIRSTSEARCH_DIR_NEXTSEARCH_MAKECOMPARE_NEXT_LOOPCOMPARE_EXTENDCOMPARE_NEXT_CHARRETURN_DIR_CODEENTRY_NOT_FOUNDERASE_FILES |ERASE_LOOPALLOCATE_NEXT_BLOCKALLOCATE_NEXT_LOOPALLOCATE_HIGHERALLOCATE_BLOCKALLOCATE_LOWERWRITE_COMPLETE_ENTRYWRITE_PARTIAL_ENTRYWRITE_DIR_RECORD_RENAME_FILERENAME_LOOP_SET_FILE_ATTRSET_ATTR_LOOP_OPEN_FILEOPEN_ENTRYSET_RECORD_COUNTCLOSE_WORD_BLOCKCLOSE FILE
259
Labels
'i*- • •*-* :*•<
St\ •.„-...**, I („
08CDH08D4H08DBH08E1H08E8H08FDH0917H091FH0924H0946H095AH0983H098EH09 ACH09AFH09B6H09BCH09C1H09E6H09FBH09FEH'OA03HOA3BHOA43HOA48HOA64HOA6CHOA6EHOA8CHOA9AHOABBHOAD2HOAFEHOBOOHOB03HOB07HOB47HOB7FHOB84HOB8BHOB93HOB9CHOBA5HOBD2HOBE4HOC06HOCOCHOCOEHOC21HOC45HOC51HOC75HOC7EHOC83H
CLOSE_BLOCK_LOOPBYTE_BLOCK_CLOSECLOSE_BYTE_BLOCKSAME_BYTE_BLOCK ?WORD_BLOCK_CLOSECLOSE_NEXT_BLOCKWRITE_CLOSED_ENTRYCANT_CLOSE |_MAKE_FILEMAKE_CLEAR_LOOPOPEN_NEXT_EXTENDNEW_EXT_TOO_BIGSEARCH_NEXT_EXTENDENTRY_FOUNDNEW_EXTEND_OPENEDCANT_EXTEND_FILE_READ_SEQUREAD_RND_SEQREAD_NEXT_RECORDEND_OF_FILE_WRITE_SEQUWRITE_RND_SEQWRITE_NEW_ENTRYDISK_FULLWRITE_NEW_BLOCKNEW_BLOCK_WORDBLOCK_WRITE_NEWBLOCK_WRITE_NORMALZERO_WRITE_BUFFERBLOCK_WRITE_LOOPWRITE_ACTUAL_DATASTILL_IN_CURRENT_EXTCLEAR_EXIT_VALUEJP_UPDATE_RECORD_#STRNS_RND_TO_SEQZERO_TRANS_R_TO_SDIFFERENT_EXTENDCORRECT_RND_ACCESSBAD_RND_ACCESSRND_SEEK_ERROR_READ_RANDOM_WRITE_RANDOMTRANS_SEQ_TO_RND_COMPUTE_FILE_SIZECOMPUTE_SIZ E_LOOPNOT_GREATER |POP_HL?SET_RANDOM_RECORDLOGIN_CURRENT_DISK?SELECT_DISKAUTO_SELECTNO_AUTO_SLCT?RETURN_VERSION_#7RESET DISK SYSTEM
260
OC9CHOCA5HOCABHOCC2HOCC8HOCD7HOCEOHOCE6HOCECHOCF5HOCFEHOD04HODOAHOD1 1 HOD17HOD1DHOD26HOD29HOD2DHOD3BHOD41HOD47HOD4DHOD53HOD74HOD91HOD9BHODACHODADHODAFHODB1HODB3HODB5HODB7HODB9HODB3HODBDHODBFHODC1HODC3HODC4HODC5HODC6HODC8HODCAHODCCHODCEHODDOHODD2HODD3HODD4HODD5HODD6HODD7H
Labels
?OPEN_FILE?CLOSE_FILE?SEARCH_FIRSTSEARCH_NOW?SEARCH_NEXT?DELETE_FILE?READ__SEQU?WRITE_SEQU?MAKE_FILE?RENAME_FILE?RETURN_LOGIN_VEC?RETURN_CURRENT_DISK7SETJDMA?GET_ALLOCATION_ADDR?GET_RO_VEC?SET_FILE_ATTR?GET_PARAMETER_ADDRRETURN_WORD?SET_GET_USER_CODESET_USER_CODE?READ_RANDOM?WRITE_RANDOM?COMPUTE_FILE_SIZE?RESET_DISK?BDOS_EXITRET_TG_USER?WRITE_ZERO_RANDOM§MAKE_FCB§RO_VEC§LOGIN_VEC§BDOS_DMA_ADDRESS?§END_OF_ENTRIES?§TRACK_#?§TRACK_RECORD_#?§DIRBUF?§DPB?§CSV?§ALV§SPT§BSH§BLM§EXM§DSM§DRM§ALO_AL1§CKS§OFF?§XLTAB§ENTRY_CLOSED?§READ_OR_WRITE?§FILE_FOUND?§SEQUENTIAL?§ENTRY_BYTE§BLOCK OFFSET
261
Labels
ODD8HODD9HODDDHODDERODDFHODEOHODE1HODE2HODE3HODE5HODE5HODE7HODE9HODEAHODECHOEOOHOEOOHOE03HOE06HOE09HOEOCHOEOFHOE12HOE15HOE1 8HOE1BHOE1EHOE21HOE24HOE27HOE2AHOE2DHOE30H
§COMPARE_COUNT?§SEARCH_FCB§LARGE_DSM?§AUTO_SELECTED?§DEFAULT_DISK§FCB_DISK_#§EXT_RECORD_COUNT§CURRENT_EXTEND_#§CURRENT_SEQU_REC§ABSOLUTE_RECORD_#§BLOCK_#§BLOCK_START_RECORD§DIR_OFFSET§DIR_ENTRY_#§DIR_RECORD_#BIOSB_CBOOTB_WBOOTB_CONSTB_CONINB_CONOUTB_LISTB_PUNCHB_READERB_HOMEB_SELDSKB_SETTRKB_SETSECB_SETDMAB_READB_WRITEB_LISTSTB SECTRN
262
3-925O74-II-2