/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
// Mistumi LS005 commands
// ALl commands return AT least Drive Status


#define TimeOut              0xff
#define SearchCount            2000
#define Spincount            0x4ee0L
#define ReadSpinCount        0x8AA0L
#define ReadToc                0x10
#define ReadDiscInfo           0x11
#define ReadSubQ               0x20
#define RequestSense           0x30
#define RequestDriveStatus     0x40
#define SetDriveMode           0x50
#define Reset                  0x60
#define Hold                   0x70
#define HoldTime        (UCHAR)0x80
#define GetAudioVolume  (UCHAR)0x8E
#define DriveConfig            0x90
#define ModeSet         (UCHAR)0xA0
#define ReadUPC         (UCHAR)0xA2
#define SetAudioVolume  (UCHAR)0xAE
#define ReadSubCode            0xB0
#define Seek            (UCHAR)0xC0
#define PlayAudioMSF    (UCHAR)0xC1
#define ReadDriveMode   (UCHAR)0xC2
#define Read            (UCHAR)0xC3
#define ReadFast        (UCHAR)0xC1
#define SetInterleave   (UCHAR)0xC8
#define GetVersion      (UCHAR)0xDC
#define Stop            (UCHAR)0xF0
#define Eject           (UCHAR)0xF6
#define Close           (UCHAR)0xF8
#define LockUnlock      (UCHAR)0xFE
#define SuspendData     0x0C
#define ReleaseData     0x04

#define DataReg   0
#define StatusReg 1

// Drive status bit definitions
// base adapter address +1 (301h for example)

#define DoorOpen     0x80 // 1 = door open
#define DiscIn       0x40 // 1 = disc in
#define DiscChg      0x20 // 1 = disc changed
#define Spinup       0x10 // 1 = disc spinning
#define AudioDisc    0x08 // 1= Audio
#define ReadError    0x04 // 1 = error, see sense data
#define AudioBusy    0x02 // 1 = playback in progress
#define CommandCheck 0x01 // 1 = command error
#define COMMANDCHECK(x) ((LOBYTE(x) & CommandCheck))
#define DOOROPEN(x) ((LOBYTE(x) & DoorOpen))
#define TIMEOUT(x) ((HIBYTE(x)==TimeOut))
#define DUMMYWAIT  { USHORT i=0x4000;while(i)i--;}
#define SHORTWAIT  { USHORT i=0x0100;while(i)i--;}
#define DISCCHANGE(x)  ((LOBYTE(x) & DiscChg))
#define DISCIN(x)      ((LOBYTE(x) & DiscIn))
#define READERROR(x)   ((LOBYTE(x) & ReadError))
#define AUDIODISC(x)   ((LOBYTE(x) & AudioDisc))
#define AUDIOBUSY(x)   ((LOBYTE(x) & AudioBusy))
#define SPINNING(x)    ((LOBYTE(x) & Spinup))

union   OutputCommands {
        UCHAR Command;
        struct {
               UCHAR c;
               UCHAR Min;
               UCHAR Sec;
               UCHAR Frame;
               UCHAR Rsv[3];
               } SeekCmd;
        struct {
               UCHAR c;
               UCHAR Min;
               UCHAR Sec;
               UCHAR Frame;
               UCHAR Length1;
               UCHAR Length2;
               UCHAR Length3;
               } ReadCmd;
        struct {
               UCHAR c;
               UCHAR StartMin;
               UCHAR StartSec;
               UCHAR StartFrame;
               UCHAR StopFrame;
               UCHAR StopMin;
               UCHAR StopSec;
               } PlayAudio;
        struct {
               UCHAR c;
               UCHAR ModeType;
               #define Mode0 0
               #define Mode1 1
               #define Mode2 2
               } DataModeSet;

        struct {
               UCHAR c;
               UCHAR UnitsofTenSeconds;
               // Default is 0C= 120 seconds, 01-FF valid
               } HoldCmd;

        struct {
               UCHAR c;
               UCHAR Mode;
               // drive modes used in command 0x50 (set) and 0xC2 (get)

               #define TestMode   0x80   // 0 = bit 6 (next bit) is valid
               #define DataLength 0x40   // 1 = 2352, 2048 user data
                                         // 0 = 2048 user data only
               #define EccBit     0x20   // 0 = yes secondary correction after CIRC error
                                         // 1 = no correction
               #define RsvMode1   0x10   // reserved, set to 0 on write
               #define SpinDisc   0x08   // 1 = spindown
                                         // 0 = spinup
               #define TocData    0x04   // 1 = read TOC on ReadSubQ (0x20)
               #define RsvMode2   0x02
               #define MuteData   0x01   // 1 = no audio playback of data tracks
                                         // 0 = always muted
               } DriveMode;

        struct {
               UCHAR c;
               union {
                     UCHAR  Byte;
                     struct {
                            UCHAR  ByteLength:1;
                                   // if True
                                   // Byte 2 = MSB of block length
                                   // Byte 3 - LSB of block length
                            UCHAR  DMAMode:1;
                                   // if True Data Transfers use DMA, Regardless of this bit, ONLY Data can use DMA, nothing else
                            UCHAR  UPCCode:1;
                                   // If True
                                   // Issue ReadUpc (0xA2) as next command
                            UCHAR  DMATimeut:1;
                                   // if True
                                   // Byte2 = millisecond timeout value
                            UCHAR  IRQEnable:1;
                                   // if IRQEnable = True
                                   // Byte2 settings
                                      #define PreIrq  1
                                      #define PostIrq 2
                                      #define ErrIrq  4
                            UCHAR  RetryCount:1;
                                   // byte2 count
                            UCHAR  Reserved:2;
                            } Bits;
                      } Byte1;
               UCHAR  Byte2;
               UCHAR  Byte3;
               } DriveConfigCmd;
               #define RETRYCOUNT 0x20L
               #define IRQFLAG 0x10L
               #define DMAFLAG 0x08L
               #define UPCFLAG 0x04L
               #define GetSubq 0
               #define GetUpc  1
               #define MODEFLAG 0x02L
               #define BLOCKSIZE 0x01L

               // don't know why we'd use this command yet, reads P-W subchannels all at once, 98 bytes returned
        struct {
               UCHAR c;
               UCHAR  Min;
               UCHAR  Sec;
               UCHAR  Frame;
               UCHAR Length1; // MSB
               UCHAR Length2;
               UCHAR Length3; // LSB
               } ReadSubCode_n_Block;

        struct {
               UCHAR c;
               UCHAR ATT0;
               UCHAR ATT1;
               UCHAR ATT2;
               UCHAR ATT3;

                 // table of settings
                 // ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
                 // ³ Att0 ³ Att1 ³ Att2 ³ Att3 ³ Right Ch ³ Left Ch  ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  00  ³  01  ³  00  ³   On     ³   On     ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  00  ³  01  ³  00  ³   On     ³   Off    ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  00  ³  00  ³  00  ³   Off    ³   On     ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  00  ³  01  ³  01  ³  Mono From Right Ch ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  01  ³  00  ³  00  ³  Mono From Left  Ch ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  01  ³  01  ³  01  ³      Mixing         ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  01  ³  00  ³  01  ³      Reverse        ³
                 // ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

               } AudioLevel;

        struct {
               UCHAR c;
                UCHAR Size;
                // Default = Minimum = 1;
                // Value is decremented by 1 at drive, so 1 = 0 = No interleave
               } InterLeave;
        struct {
               UCHAR c;
               UCHAR Option;
               #define Unlock 0
               #define Lock 1
               #define Query  2
               } LockDrawer;
        } ;

typedef union   CommandResults {
        struct {
               UCHAR Code; // always 'M'
               UCHAR VerLSN:4;
               UCHAR VerMSN:4;
               } Version;

        struct {
               UCHAR SenseKey;
               // Only valid if ReadError or Drive_Status is on
               #define No_Error      0
               #define ModeMismatch  1
               #define BlockNotFound 2
               #define FatalError    3
               #define SeekError     4
               } SenseData;

        struct t {
               struct {
                      UCHAR ADR:4;
                      UCHAR Control:4;
                       }S;
               UCHAR TNO;
               UCHAR Index;
               UCHAR Min;
               UCHAR Sec;
               UCHAR Frame;
               UCHAR Zero;
               UCHAR AMin;
               UCHAR ASec;
               UCHAR AFrame;
               } TrackInfo;
               #define MinFrame 0x00000200L             // 2 min, 0 seconds

        struct {
               UCHAR FirstTrack;
               UCHAR LastTrack;
               UCHAR LeadoutMin;
               UCHAR LeadoutSec;
               UCHAR LeadoutFrame;
               UCHAR FirstTrackMin;
               UCHAR FirstTrackSec;
               UCHAR FirstTrackFrame;
               } TOC;

        struct {
               UCHAR ATT0;
               UCHAR ATT1;
               UCHAR ATT2;
               UCHAR ATT3;

                 // table of settings
                 // ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
                 // ³ Att0 ³ Att1 ³ Att2 ³ Att3 ³ Right Ch ³ Left Ch  ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  00  ³  01  ³  00  ³   On     ³   On     ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  00  ³  01  ³  00  ³   On     ³   Off    ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  00  ³  00  ³  00  ³   Off    ³   On     ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  00  ³  01  ³  01  ³  Mono From Right Ch ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  01  ³  00  ³  00  ³  Mono From Left  Ch ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  01  ³  01  ³  01  ³  01  ³      Mixing         ³
                 // ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
                 // ³  00  ³  01  ³  00  ³  01  ³      Reverse        ³
                 // ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

               } AudioLevel;

        struct {
               UCHAR Mode;
               // drive modes used in command 0x50 (set) and 0xC2 (get), see 0x50 for values
               } DriveMode;

        struct {
                UCHAR Size;
                // Default = Minimum = 1;
                // Value is decremented by 1 at drive, so 1 = 0 = No interleave
               } InterLeave;
        struct {
                UCHAR State;
                #define Unlocked 0
                #define Locked 1
                // Value is decremented by 1 at drive, so 1 = 0 = No interleave
               } LockStatus;
        struct {
               UCHAR Control:4;
               UCHAR ADR:4;
               UCHAR UPCCode[7];
               UCHAR Zero;
               UCHAR AFrame;
               } UPC;
        struct {
               UCHAR Type;
               // Disc types, see DataMode command above
               // Mode1 = Multi-Session Photo CD
               // if Mode1, then these values are the first sector of last session
               // else all zeros
               UCHAR Min;
               UCHAR Sec;
               UCHAR Frame;
               } DiscInfo;

        } CDROMSTAT, *PCDROMSTAT, near * nPCDROMSTAT ;

typedef struct {
       UCHAR Sync1[12];
       UCHAR Header[4];
       UCHAR Subheader1[4];
       UCHAR Subheader2[4];
       UCHAR Data[2048];
       UCHAR ECCbits[280];
       } RawSector, *PRawSector;

#define Disable _asm { cli }
#define Enable  _asm { sti }
#define STEN 4                  // status Enable, when 0, status is available
#define DTEN 2                  // data Enable, when 0, data is available

#define DefaultDiscSize    270000L

typedef struct TOCInfo
{
   UCHAR          min;
   UCHAR          sec;
   UCHAR          frame;
   UCHAR          Control:4;
   UCHAR          ADR:4;
   ULONG          start;
} TOCINFO ;

#ifdef DEBUG
#define DPRINTF(x)   printf x ; flushall();
#else
#define DPRINTF(x)
#endif
#define SET_VS             0x04
#define SET_TI             0x08

#define CLR_TI             0xF7
#define CLR_VS             0xFB

#define TCI_DATA           0x04
#define TCI_AUDIO          0x00
#define CDXA               0x20

#define CHANGED         -1
#define DONT_KNOW       0
#define NOT_CHANGED     1
#define I386            (UCHAR)1
#define I486            (UCHAR)2

#ifdef TRACE
#define DevHelp_RAS(w,x,y,z) DevHelp_RAS(w,x,y,z)
#else
#define DevHelp_RAS(w,x,y,z)
#endif
#if defined(TRACE1) | defined(TRACE)
#define DevHelp_RAS1(w,x,y,z) DevHelp_RAS(w,x,y,z)
#else
#define DevHelp_RAS1(w,x,y,z)
#endif
#define NoIrq   0
#define Oti12   0x00
#define Irq9    0x10
#define Irq3    0x20
#define Irq5    0x30
#define Irq10   0x40
#define Irq11   0x50
#define Irq12   0x60
#define Irq15   0x70

typedef struct _MSGTABLE {              /* DHMT */

  USHORT   MsgId;                       /* Message Id #                  */
  USHORT   cMsgStrings;                 /* # of (%) substitution strings */
  PSZ      MsgStrings[1];               /* Substitution string pointers  */
} MSGTABLE;

#define MSG_REPLACEMENT_STRING 1178

