/*
**      $VER: CD-ROM.h 0.17 (28.7.97)
**      ACDPlay Release 1.49 beta
**
**      Definitions and prototypes for the CD-ROM module for ACDPlay
**
**      (C) Copyright 1997 Martin Kresse and Marc Altmann
**                  All Rights Reserved
*/


/* Eintrag für jeden Track der CD. Entry[0] und Entry[LastTrack+1] haben
 * die Tracknummer 0xAA und beinhalten die Daten der lead-out area, einem
 * Bereich, der hinter dem letzten Track liegt und nicht mehr lesbar ist.
 * Die Bits des CtlAdr-Bytes haben folgende Bedeutung:
 *
 *  Bit           equals zero                   equals one
 * ------------------------------------------------------------------
 *
 *   0       Audio without pre-emphasis    Audio with pre-emphasis
 *   1       Digital copy prohibited       Digital copy permitted
 *   2       Audio track                   Data track
 *   3       Two channel audio             Four channel audio
 *
 */
struct CDTOCEntry {
        UBYTE           reserved1;
        UBYTE           CtlAdr;         /* Sub-channel Q Kontroll Bits */
        UBYTE           Track;          /* Tracknummer */
        UBYTE           reserved2;
        LONG            Address;        /* Adresse vom ersten Blocks dieses Tracks */
};

#define QCONTROLB_PREEMPHASIS   0
#define QCONTROLB_COPYSTATUS    1
#define QCONTROLB_DATA          2
#define QCONTROLB_FOURCHANNEL   3

#define QCONTROLF_PREEMPHASIS   (1<<QCONTROLB_PREEMPHASIS)
#define QCONTROLF_COPYSTATUS    (1<<QCONTROLB_COPYSTATUS)
#define QCONTROLF_DATA          (1<<QCONTROLB_DATA)
#define QCONTROLF_FOURCHANNEL   (1<<QCONTROLB_FOURCHANNEL)


/* Diese Struktur wird von CDReadTOCA() gefüllt, und, wenn CDUpdateA()
 * einen Disc-Wechsel mitbekommt
 */
struct CDxTOC {
        UBYTE           FirstTrack;         /* Erster Track, muß nicht 1 sein! */
        UBYTE           LastTrack;          /* Letzter Track, max. 99 */
        UBYTE           TrackNum;           /* Anzahl der Tracks */
        UBYTE           FirstAudioTrack;    /* Erster Audiotrack auf der CD oder 0 */
        ULONG           FirstAudioAddress;  /* Adresse des ersten Audiotracks */
        CDTOCEntry      Entry[101];         /* für jeden Track ein Eintrag plus 2xlead-out */
        UBYTE           CDID[20];           /* ID für Diskfiles */
};

/* CDxRequest wird von CDOpenDeviceA() zurückgegeben und enthält alle wichtigen
 * Daten über das CD-ROM Laufwerk, Zeiger auf CD-spezifische Strukturen und
 * diverse private Zeiger. ALLE Felder sind read-only und werden von den
 * zuständigen Funktionen verändert.
 */
struct CDxRequest {

    /* Diese Felder werden von CDUpdateA() aktualisiert
    */
    UBYTE       cdx_CurrentTrack;       /* Aktuelle Tracknummer */
    UBYTE       cdx_CurrentIndex;       /* Aktueller Index im aktuellen Track */
    LONG        cdx_CurrentAbsAddr;     /* Aktuelle Position relativ zum Anfang des Mediums als logical block address */
    LONG        cdx_CurrentRelAddr;     /* Aktuelle Position relativ zum Anfang des aktuellen Tracks als logical block address*/
                                        /* Dieser Wert kann innerhalb einer pre-gap area negativ sein. */
    LONG        cdx_RelRemainBlocks;    /* Verbleibende Blöcke des aktuellen Tracks */
    LONG        cdx_AbsRemainBlocks;    /* Verbleibende Blöcke der ganzen CD */
    ULONG       cdx_TrackLength;        /* Länge des Tracks in Blöcken */
    UBYTE       cdx_AudioStatus;        /* Audio Status Byte */
    UBYTE       cdx_Active;             /* Simplifiziertes Audio Status Byte zwecks CDPlayLib Kompatibilität*/

    /* CDGetVolumeA()
    */
    UBYTE       cdx_Volume[4];          /* Lautstärke (0-255) des jeweiligen Kanals */

    /* CDOpenDeviceA()
    */
    UBYTE       cdx_DeviceType;         /* Device Type */
    UBYTE       cdx_Unit;               /* Unit */
    UBYTE       cdx_LUN;                /* LUN */
    UBYTE       cdx_reserved1;
    char       *cdx_DeviceName;         /* Devicename */
    UBYTE       cdx_Flags;              /* spezielle, hauptsächlich intern genutzte Flags */

    /* Wird von jedem mißglücktem SCSI-Kommando gesetzt.
    */
    UBYTE       cdx_SenseKey;
    UBYTE       cdx_AddSenseCode;
    UBYTE       cdx_AddSenseCodeQual;

    /* CDReadTOCA()
    */
    CDxTOC     *cdx_TOCData;            /* Zeiger auf ein CDxTOC Struktur */

    /* Die folgenden Felder sind eigentlich privat... ;-)
    */
    APTR        cdx_ValidAudioPage;     /* welche Werte der Mode Audio Page verändert werden dürfen */
    UBYTE      *cdx_SCSIData;           /* Datenpuffer */
    UBYTE      *cdx_SCSISense;          /* Mode Sense-Puffer oder NULL*/
    MsgPort    *cdx_IOPort;
    IOStdReq   *cdx_IORequest;
    MsgPort    *cdx_CDPlayPort;         /* für 2. IORequest, da das "cd.device" */
    IOStdReq   *cdx_CDPlayIORequest;    /* kein asynchrones abspielen beherrscht */
    Library    *cdx_SysBase;            /* ExecBase, um Chip-RAM-Zugriffe zu vermeiden... */
    APTR        cdx_MemStart;
    APTR        cdx_SCSIDataStart;

    /* Diese Zeiger können genutzt werden (kann manchmal ganz interessant sein :-)
    *  Achtung: Vorher auf NULL testen (wegen cd-/scsi.device).
    */
    SCSICmd    *cdx_Cmd;
    CDInfo     *cdx_Info;
    QCode      *cdx_QCode;

    /* Das hier wird nur beim Öffnen initialisiert.
    */
    char       *cdx_Vendor;             /* Hersteller (z.B. "Toshiba Japan") */
    char        cdx_VendorID[9];        /* Hersteller ID (z.B. "TOSHIBA") */
    char        cdx_Product[17];        /* Produktname */
    char        cdx_Revision[5];        /* Herstellerspezifische Revision */
    char        cdx_Specific[21];       /* 20 Bytes herstellerabhängiges Zeugs (auch ASCII) */
};


/* Diese Macros dürften bekannt sein ;-)
*/
#define base2sec(val) (((val)/75)%60)
#define base2min(val) ((val)/75/60)
#define base2frm(val) (val%75)


/* Flags für AudioAttr-Struktur
*/
#define AUDIOB_SOTC     0
#define AUDIOB_IMMED    1
#define AUDIOF_SOTC     (1<<AUDIOB_SOTC)
#define AUDIOF_IMMED    (1<<AUDIOB_IMMED)


/* cdx_Flags
*/
#define SPECIALB_ATAPI          6   /* "cd.device" wird benutzt */
#define SPECIALF_ATAPI          (1<<SPECIALB_ATAPI)

#define SPECIALB_JUSTCLOSED     5   /* für automatisches Open/Close */
#define SPECIALF_JUSTCLOSED     (1<<SPECIALB_JUSTCLOSED)

#define SPECIALB_LOCKED         4   /* ob die Schublade verschlossen ist */
#define SPECIALF_LOCKED         (1<<SPECIALB_LOCKED)


/* Audio Status Codes
*/
#define AUDIO_STAT_NOT_VALID    0x00    /* Audio status byte not supported or not valid */
#define AUDIO_STAT_NO_DISK      0x10    /* Medium not present */
#define AUDIO_STAT_PLAYING      0x11    /* Audio play operation in progress */
#define AUDIO_STAT_PAUSED       0x12    /* Audio play operation paused */
#define AUDIO_STAT_COMPLETED    0x13    /* Audio play operation successfully completed
                                         * This value is returned only once! */
#define AUDIO_STAT_STOPPED      0x14    /* Audio play operation stopped due to error
                                         * This value is returned only once! */
#define AUDIO_STAT_NONE         0x15    /* No current audio status to return */


/* Device Types
*/
#define DEVTYPE_DIR_ACCESS      0x00    /* Direct-access device (e.g., magnetic disk) */
#define DEVTYPE_SEQ_ACCESS      0x01    /* Sequential-access device (e.g., magnetic tape) */
#define DEVTYPE_PRINTER         0x02    /* Printer device */
#define DEVTYPE_PROCESSOR       0x03    /* Processor device */
#define DEVTYPE_WRITE_ONCE      0x04    /* Write-once read-multiple device (e.g., some optical disks) */
#define DEVTYPE_CDROM           0x05    /* CD-ROM device */
#define DEVTYPE_SCANNER         0x06    /* Scanner device */
#define DEVTYPE_OPTICAL         0x07    /* Optical memory device (e.g., some optical disks) */
#define DEVTYPE_CHANGER         0x08    /* Medium Changer device (e.g., jukeboxes) */
#define DEVTYPE_COMM            0x09    /* Communications device */
#define DEVTYPE_GFX_1           0x0A    /* Defined by ASC IT8 */
#define DEVTYPE_GFX_2           0x0B    /* (Graphics Pre-Press Devices) */
#define DEVTYPE_RESERVED1       0x0C    /* Reserved */
#define DEVTYPE_RESERVED2       0x0D
#define DEVTYPE_RESERVED3       0x0E
#define DEVTYPE_UNKNOWN         0x1F    /* Unknown or no device type */


/* Prototypes
*/
extern struct CDxRequest *CDOpenDeviceA(register __a0 char *devicename, register __d0 ULONG unitnumber, register __d1 ULONG lun);
extern BOOL CDCloseDeviceA(register __a0 struct CDxRequest *cdx);
extern BOOL CDChangeDeviceA(register __a0 struct CDxRequest *cdx, register __d0 ULONG unitnumber, register __d1 ULONG lun);

extern LONG CDTestUnitA(register __a0 struct CDxRequest *cdx);
extern LONG CDUpdateA(register __a0 struct CDxRequest *cdx);
extern LONG CDReadTOCA(register __a0 struct CDxRequest *cdx);
extern LONG CDDoSCSIA(register __a0 struct CDxRequest *cdx, register __a1 APTR Command, register __d0 UWORD Cmdlen, register __d1 LONG Flags);

extern LONG CDPauseA(register __a0 struct CDxRequest *cdx, register __d0 BOOL pause);
extern LONG CDEjectA(register __a0 struct CDxRequest *cdx, register __d0 BOOL eject);
extern LONG CDLockA(register __a0 struct CDxRequest *cdx, register __d0 BOOL lock);
extern LONG CDPlayA(register __a0 struct CDxRequest *cdx, register __d0 UBYTE starttrack, register __d1 UBYTE startindex);
extern LONG CDStopA(register __a0 struct CDxRequest *cdx);
extern LONG CDPrevA(register __a0 struct CDxRequest *cdx);
extern LONG CDNextA(register __a0 struct CDxRequest *cdx);
extern LONG CDJumpA(register __a0 struct CDxRequest *cdx, register __d0 LONG address, register __d1 BYTE jumpmode);
extern LONG CDFastModeA(register __a0 struct CDxRequest *cdx, register __d0 UBYTE mode, register __d1 UBYTE vendor);
extern LONG CDVolumeA(register __a0 struct CDxRequest *cdx, register __d0 UBYTE mode);


/* CDJumpA() kennt folgende Modi:
*/
#define JUMPMODE_SEEK_ABS   0   /* seeks to an absolute logical block address */
#define JUMPMODE_SEEK_REL   1   /* seeks relative to current position */
#define JUMPMODE_PLAY_ABS   2   /* starts playing from an absolute logical block address */
#define JUMPMODE_PLAY_REL   3   /* starts playing relative to current position */

/* Modi für CDFastModeA():
*/
#define FASTMODE_OFF        0
#define FASTMODE_FORWARD    1
#define FASTMODE_BACKWARD   2

#define GET_VOLUME  0
#define SET_VOLUME  1
