So kann es gehen: kaum bequemt man sich mal dazu, etwas Positives ĂŒber die Firma Commodore zu sagen (siehe Messebericht im letzten Heft), schon geht es ihr schlechter (vgl. Spiegel-Ausgabe vom 11. April 1994). Man darf gespannt sein, wie es dort weitergehen wird...
Die ATARI-Szene hat lange gebraucht, sich fĂŒr die CD-ROMs zu erwĂ€rmen, aber nun scheinen sie zum SelbstlĂ€ufer geworden zu sein. Der Grund sind sinkende Preise fĂŒr SCSI-Laufwerke, alternative Interfaces, ausgereiftere Treiber-Software und nicht zuletzt die nun auf den Markt drĂ€ngenden mit ATARI-Software gefĂŒllten CDs.
Im Zuge dieser Entwicklung tauchen auch immer mehr CD-Player-Programme auf. Dies ist kein groĂes Wunder, fehlt doch in ATARIs MetaDOS-Paket ein entsprechendes Programm. Und wer wollte nicht ab und zu auch mal eine Audio-CD einschieben und sich berieseln lassen?
Weniger verstĂ€ndlich ist, daĂ sich offenbar fast alle Autoren die Arbeit machen, SCSI- und ACSI-Routinen neu zu entwickeln. Dabei bringen die MetaDOS-BOS-Treiber schon den nötigen Funktionsumfang mit. Da ja wohl niemand ein CD-ROM ohne funktionstĂŒchtigen Betriebssystemtreiber besitzt (Audio-CDs abspielen geht auch billiger), gibt es wirklich keinen Grund, diese nicht auch zu benutzen.
DafĂŒr sprechen natĂŒrlich auch noch andere GrĂŒnde: wer die Betriebssystemebene wĂ€hlt, braucht sich keine Gedanken ĂŒber Kollisionen beim Zugriff auf Hardware-Register zu machen. Ferner kann man auch gleich solche Laufwerke mitbedienen, die ĂŒber ein anderes Interface (ROM-Port, IDE-Schnittstelle etc.) angeschlossen sind.
So mancher Leser wird nun nicht ganz zu Unrecht ein wenden, daĂ MetaDOS ja eigentlich ein âauslaufendesâ Modell ist und man doch an CD-ROM-Treiber unter MiNT denken sollte. Dies ist völlig richtig, und daher werden wir auch diese Möglichkeit in Betracht ziehen, wenn es auch bislang noch keine entsprechenden MiNT-Treiber (mit Audio-Funktionen) gibt.
Beginnen wir also mit MetaDOS: Diese Betriebssystemerweiterung installiert sich bekanntlich auf zwei Ebenen, nĂ€mlich GEMDOS und XBIOS. Auf GEMDOS-Ebene spiegeln die Dateisystemtreiber (â*.DOSâ) ein ganz normales GEMDOS -Laufwerk vor. Den direkten Zugriff auf die Funktionen des GerĂ€ts hat man nur ĂŒber die XBIOS-Funktionen. Die von ATARI dokumentierten Funktionen entsprechen in etwa dem, was das selige âCDAR 504â leisten konnte. Darunter sind einige Eigenheiten, die man bei ânormalenâ SCSI-Laufwerken vergeblich sucht, und einige Dinge fehlen einfach. Die Standardfunktionen eines CD-Players lassen sich so allerdings leicht implementieren.
FĂŒr einen MiNT-Treiber sieht die Sache allerdings schon anders aus. Wenn man nicht gerade die XBIOS-Erweiterungen von MetaDOS emulieren will - mancher wĂŒrde das einen âĂŒblen Hackâ nennen -muĂ man die Schnittstellen nutzen, die MiNT dafĂŒr bietet. Dies sind die GEM-DOS-Funktionen Dcntl() und Fcntl(), mit denen man spezielle Eigenschaften von GerĂ€ten steuern kann. Dabei bekommt Dcntl() den Namen einer Datei und Fcntl() das Handle einer Datei.
Dies entspricht dem Unix-Programmiermodell, und so ist es naheliegend, sich auf Unix-Implementationen nach CD-ROM-spezifischen Opcodes umzusehen und diese entsprechend zu ĂŒbernehmen. Genau dies wurde zu RedaktionsschluĂ gerade gemacht.
Wie schon oben erwĂ€hnt, unterstĂŒtzt das Standard-MetaDOS-Interface nicht alles, was man mit einem modernen CD-ROM machen kann (und will). Die offensichtliche Lösung ist, dieselben Funktionen, die auch ĂŒber das Fcntl()-Interface verfĂŒgbar sind, ebenso ĂŒber einen MetaDOS-XBIOS-Aufruf anzubieten. Und wenn dann auch noch MetaDOS selbst und der DOS-Treiber die Funktion Dcntl() unterstĂŒtzen und entsprechend an den CD-ROM-Treiber weiterleiten, hat man eine BinĂ€rkompatibilitĂ€t zum MiNT-Interface und kann sich Fallunterscheidungen ganz ersparen.
Nochmal zusammengefaĂt:
- Eine Sammlung von Standard-Opcodes fĂŒr Fcntl() bzw. Dcntl() zur Steuerung von CD-ROMs ist zur Zeit in Arbeit und wird in einer der nĂ€chsten Ausgaben vorgestellt.
- Autoren von BOS-Treibern sollten diese Funktionen zusĂ€tzlich zum normalen MetaDOS-XBIOS-Funktionsumfang unterstĂŒtzen.
- Kommende Versionen von MetaDOS erlauben es, fĂŒr CD-ROM-Dateisysteme die Funktion Dcntl() zu benutzen (was die Mitarbeit des entsprechenden BOS-Treibers voraus setzt).
Diesen Monat will ich aber erst einmal auf das eingehen, was alle existierenden MetaDOS-Treiber schon unterstĂŒtzen (sollten). Die Abbildungen zeigen entsprechende Bindings fĂŒr PureC.
Die XBIOS-Ebene von MetaDOS arbeitet mit eigenstĂ€ndigen Laufwerksbuchstaben (von âAâ bis âZâ), die freilich nichts mit den GEMDOS-Laufwerksbuchstaben zu tun haben. Dies sind die Buchstaben, die in der Datei CONFIG.SYS im Zusammenhang mit den B OS-Dateien angegeben sind. Alle XBIOS-Funktionen mit Ausnahme von Metainit() erwarten diesen Laufwerksbuchstaben als ersten Parameter.
Metainit() initialisiert MetaDOS und liefert Informationen zurĂŒck. Dabei hat man ausnahmsweise bei ATARI vorausgedacht und die Funktion so deklariert, daĂ man auch feststellen kann, ob sie ĂŒberhaupt ausgefĂŒhrt wurde (was ja bei XBIOS-Funktionen bekanntlich ein Problem darstellt).
Metainit() fĂŒllt eine META_INFO_1-Struktur aus, deren Anfangsadresse man als Parameter ĂŒbergibt. Das erste Element dieser Struktur (mi_drivemap) ist eine âDrivemapâ, wie man sie bereits von BIOS [Drvmap()] und GEMDOS [RĂŒckgabewert von Dsetdrv()] kennt. Hier steht sie fĂŒr die installierten MetaDOS-GerĂ€te. MetaDOS wird nur dann installiert, wenn auch ein GerĂ€t gefunden wurde. Löscht man mi_drivemap vor dem Aufruf, kann man also nachher leicht erkennen, ob MetaDOS installiert ist.
Weiterhin trÀgt MetaDOS in mi_version_string einen Zeiger auf einen Versions-String sowie in mijnfo einen Zeiger auf eine weitere Informationsstruktur ein. Diese Struktur ist seit Version 2.30 vorhanden und enthÀlt eine Versionsnummer (mi_version), zur Absicherung einen Magic-Wert (mi_magic) sowie einen Zeiger auf ein Feld, das zu jedem GEMDOS-GerÀt den dazugehörigen MetaDOS-Laufwerksbuchstaben oder Null enthÀlt. Mit Hilfe dieser Information kann man also feststellen, welcher MetaDOS-Laufwerksbuchstabe zu welchem GEMDOS-Laufwerk gehört.
Metaopen() initialisiert ein GerĂ€t und liefert in der âMETA_DRVINFOâ-Struktur einen Zeiger auf den Treibemamen zurĂŒck. Wenn dieser mit den Zeichen âCDâ beginnt, darf man davon ausgehen, daĂ es sich um einen CD-ROM-Treiber handelt. Metaclose() gibt das GerĂ€t wieder frei (und wird normalerweise ignoriert).
Metaread() liest Daten vom GerĂ€t. Bei CD-ROMs ist die BlockgröĂe 2048 Bytes, aber leider kann man dies nicht gezielt erfragen. Aufgrund einer Begrenzung in ATARIs BOS-Treibern kann man maximal 63 Blöcke in einem Rutsch lesen (< 128K).
Metawrite() macht bei CD-ROMs logischerweise gar nichts, könnte aber beispielsweise bei Streamer-Treibern eingesetzt werden.
Metastatus() dient dazu, den momentanen Status des GerĂ€ts zu erfragen. Der Return-Wert ist eine 32-Bit-Zahl mit einem etwas skurrilen Aufbau. Das High-Word ist entweder 0 (OK) oder 0xFFFF (Fehler). Die unteren 16 Bits enthalten verschiedene Flags: Fehler (Bit 15), Timeout (Bit 7), Medien Wechsel (Bit 2) und Busy (Bit 1). Die restlichen Bits sind reserviert. ATARIs DOS-Treiber fragt zunĂ€chst auf ânegativâ ab und testet ansonsten das Medienwechsel-Bit. Der Medienwechsel-Status wird bis zum ersten Read-Befehl beibehalten.
Metaioctl() ist die bereits erwĂ€hnte Funktion, ĂŒber die man die Opcodes der GEMDOS-Funktionen Dcntl() bzw. Fcntl() an das GerĂ€t absetzen kann, magic muĂ dabei FCTL sein. ATARIs DOS-Treiber benutzt bereits jetzt den Opcode CDROMREAD-OFFSET (0x4300), ĂŒber den die Nummmer des ersten Sektors der letzten Session einer Multisession-CD erfragt wird. Wenn der aufgerufene BOS-Treiber diese Funktion unterstĂŒtzt (CD-ARGEN.BOS tut es nicht, wohl aber andere kommerziell erhĂ€ltliche Treiber), werden also auch Multisession-CDs korrekt erkannt. buffer ist in diesem Fall ein Zeiger auf einen Long-Wert, in dem die Blocknummer eingetragen wird.
Achtung: Wenn ein BOS-Treiber diese Funktion nicht unterstĂŒtzt, liefert er entweder EINVFN (-32: dieser Opcode existiert) oder EUNKNOWN (-3: Metaioctl() wird nicht unterstĂŒtzt) zurĂŒck.
Die letzten fĂŒnf Funktionen befassen sich mit den Audio-Kommandos eines CD-ROMs und funktionieren auf anderen GerĂ€tetypen logischerweise nicht. CD-ROMs kennen zwei verschiedene Methoden zur Angabe einer Position auf der CD. Eine âLBAâ (Logical Block Address) entspricht einer Sektornummer auf einer Festplatte: die Sektoren sind, bei Null beginnend, fortlaufend durchnumeriert. Eine âMSFâ-Adresse hingegen besteht aus Minute, Sekunde und âFrameâ, wobei jede Sekunde aus 75 Frames besteht (0...74). Um die Sache noch etwas interessanter zu machen, hat der erste logische Block auf dem Medium (LBA 0) die MSF-Adresse 00:02:00.
Metasetsongtime() startet eine Audio-Wiedergabe. Dabei sind âstarttimeâ und âstoptimeâ 32 Bit groĂe BCD-Zahlen in MSF-Codierung. FĂŒr den Anfang des ersten Lieds wĂŒrde man also 0x00000200 ĂŒbergeben (die obersten acht Bits bleiben unbenutzt). Wenn man âflagâ auf eins setzt, wird im Repeat-Modus abgespielt. Dieser Modus wird meines Wissens nur von CD-ARGEN.BOS und auch nur fĂŒr das âCDAR504â unterstĂŒtzt.
Metagettoc() liefert im angegebenen Buffer das Inhaltsverzeichnis der CD zurĂŒck (buffer muĂ Platz fĂŒr 128 EintrĂ€ge haben). Jeder einzelne Eintrag besteht aus Track-Nummer (0: Record hat keine Bedeutung, 0x01...0x99: Track-Nummer in BCD-Codierung, 0xa0: âersterâ Track bei programmierter Reihenfolge, 0xa2: Ende der CD) und MSF-Adresse (jeweils BCD-Format). Wiederum ein Relikt aus der CDAR504-Zeit sind der Parameter flag sowie die speziellen Track-Nummern 0xa0 und 0xa1.
Metadiscinfo() liefert eine Informationsstruktur ĂŒber den aktuellen Status. Die Positionsangaben sind dabei wiederum im BCD-MSF-Format. Vorsicht: index wird von alten BOS-Treibern nicht gesetzt, und disctype ist bei SCSI-CD-ROMs nicht gesetzt.
Metastartaudio() dient der Audio-Wiedergabe. Auf SCSI-GerĂ€ten kann man nur einen Modus (flag == 0) benutzen: in diesem Fall ĂŒbergibt man in bytearray[0] die Anzahl der Lieder und in bytearray[1] die Nummer des ersten Lieds. Metastopaudio() schlieĂlich beendet den Audio-Betrieb.
Soviel fĂŒr diesen Monat. DemnĂ€chst folgt dann die Beschreibung der Opcodes fĂŒr Fcntl(). Bis dann!
JR
/*
Bindings for MetaDOS functions
(c)1994 by MAXON-Computer
Autor: Julian F. Reschke (jr@ma.maus.de),
17. April 1994
Free distribution and usage allowed as long as
the file remains unchanged.
*/
#include <metados.h>
#include <tos.h>
void
Metainit (META_INFO_1 *buffer)
{
xbios (0x30, buffer);
}
long
Metaopen (short drive, META_DRVINFO *buffer)
{
return xbios (0x31, drive, buffer);
}
long
Metaclose (short drive)
{
return xbios (0x32, drive);
}
long
Metaread (short drive, void *buffer, long blockno, short blks)
{
return xbios (0x33, drive, buffer, blockno, blks);
}
long
Metawrite (short drive, void *buffer, long blockno, short blks)
{
return xbios (0x34, drive, buffer, blockno, blks);
}
long
Metastatus (short drive, void *buffer)
{
return xbios (0x36, drive, buffer);
}
long
Metaioctl (short drive, long magic, short opcode, void *buffer)
{
return xbios (0x37, drive, magic, opcode, buffer);
}
long
Metastartaudio (short drive, short flag, unsigned char *bytearray)
{
return xbios (0x3b, drive, flag, bytearray);
}
long
Metastopaudio (short drive)
{
return xbios (0x3c, drive);
}
long
Metasetsongtime (short drive, short repeat, long starttime, long endtime)
{
return xbios (0x3d, drive, repeat, starttime, endtime);
}
long
Metagettoc (short drive, short flag, CD_TOC_ENTRY *buffer)
{
return xbios (0x3e, drive, flag, buffer);
}
long
Metadiscinfo (short drive, CD_DISC_INFO *p)
{
return xbios (0x3f, drive, p);
}
/*
Defines and prototypes for MetaDOS functions
(c)1994 by MAXON-Computer
Autor: Julian F. Reschke (jr@ms.maus.de),
17. April 1994
Free distribution and usage allowed as long as
the file remains unchanged.
*/
#ifndef _METADOS_H
#define _METADOS_H
typedef struct
{
unsigned char trackno, minute, second, frame;
} CD_TOC_ENTRY;
typedef struct
{
unsigned char disctype; /* 0: audio, 1: data */
unsigned char firsttrack, lasttrack, curtrack;
unsigned char relposz, relposm, relposs, relposf;
unsigned char absposz, absposm, absposs, absposf;
unsigned char endposz, endposm, endposs, endposf;
unsigned char index, res[3];
unsigned long reserved[123];
} CD_DISC_INFO;
typedef struct {
unsigned short mi_version; /* 0x230 == '02.30' */
long mi_magic; /* == '_MET' */
/* maps DOS-IDs to MetaDOS XBXOS device numbers */
const char *mi_log2phys;
} META_INFO_2;
typedef struct
{
unsigned long mi_drivemap;
const char *mi_version_string;
long reserved;
META_INFO_2 *mi_info;
} META_INFO_1;
typedef struct
{
char *mdr_name;
long res[3];
} META_DRVINFO;
void
Metainit (META_INFO_1 *);
long
Metaopen (short drive, META_DRVINFO *buffer);
long
Metaclose (short drive);
long
Metaread (short drive, void *buffer, long blockno, short blks);
long
Metawrite (short drive, void *buffer, long blockno, short blks);
long
Metastatus (short drive, void *buffer);
long
Metaioctl (short drive, long magic, short opcode, void *buffer);
long
Metasetsongtime (short drive, short repeat, long starttime, long endtime);
long
Metagettoc (short drive, short flag, CD_TOC_ENTRY *buffer);
long
Metadiscinfo (short drive, CD_DISC_INFO *p);
long
Metastartaudio (short drive, short flag, unsigned char *bytearray);
long
Metastopaudio (short drive);
#endif
Julian F. Reschke