📄 i_cdmus.c
字号:
//**************************************************************************
//**
//** i_cdmus.c
//**
//**************************************************************************
// HEADER FILES ------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <stddef.h>
#include <string.h>
#include "h2def.h"
#include "i_sound.h"
// MACROS ------------------------------------------------------------------
#define MAX_AUDIO_TRACKS 25
#define MULTIPLEX_INT 0x2f
#define CDROM_GETDRIVECOUNT 0x1500
#define CDROM_SENDDEVICEREQ 0x1510
#define CDROM_GETVERSION 0x150c
#define HSG_MODE 0
#define RED_MODE 1
#define DRC_IOCTLINPUT 0x03
#define DRC_IOCTLOUTPUT 0x0c
#define DRC_PLAYAUDIO 0x84
#define DRC_STOPAUDIO 0x85
#define DRC_RESUMEAUDIO 0x88
#define DPMI_INT 0x31
#define DPMI_ALLOCREALMEM 0x0100
#define DPMI_FREEREALMEM 0x0101
#define DPMI_SIMREALINT 0x0300
// IOCTL input commands
#define ADRDEVHEAD 0 // Return Address of Device Header
#define HEADLOCATION 1 // Location of Head
#define RESERVED 2 // Reserved
#define ERRSTATISTICS 3 // Error Statistics
#define AUDIOCHANINFO 4 // Audio Channel Info
#define READDRVBYTES 5 // Read Drive Bytes
#define DEVICESTATUS 6 // Device Status
#define GETSECTORSIZE 7 // Return Sector Size
#define GETVOLSIZE 8 // Return Volume Size
#define MEDIACHANGED 9 // Media Changed
#define AUDIODISKINFO 10 // Audio Disk Info
#define AUDIOTRACKINFO 11 // Audio Track Info
#define AUDIOQCHANINFO 12 // Audio Q-Channel Info
#define AUDIOSUBINFO 13 // Audio Sub-Channel Info
#define UPCCODE 14 // UPC Code
#define AUDIOSTATUSINFO 15 // Audio Status Info
// IOCTL output commands
#define EJECTDISK 0 // Eject Disk
#define DOORLOCK 1 // Lock/Unlock Door
#define RESETDRIVE 2 // Reset Drive
#define AUDIOCHANCONTROL 3 // Audio Channel Control
#define WRITEDEVCONTROL 4 // Write Device Control String
#define CLOSETRAY 5 // Close Tray
// TYPES -------------------------------------------------------------------
typedef signed char S_BYTE;
typedef unsigned char U_BYTE;
typedef signed short S_WORD;
typedef unsigned short U_WORD;
typedef signed int S_LONG;
typedef unsigned int U_LONG;
typedef struct {
U_LONG size;
void **address;
U_WORD *segment;
U_WORD *selector;
} DOSChunk_t;
typedef struct {
U_LONG edi;
U_LONG esi;
U_LONG ebp;
U_LONG reserved;
U_LONG ebx;
U_LONG edx;
U_LONG ecx;
U_LONG eax;
U_WORD flags;
U_WORD es;
U_WORD ds;
U_WORD fs;
U_WORD gs;
U_WORD ip;
U_WORD cs;
U_WORD sp;
U_WORD ss;
} RegBlock_t;
typedef struct {
short lengthMin;
short lengthSec;
int redStart;
int sectorStart;
int sectorLength;
} AudioTrack_t;
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static U_WORD InputIOCTL(S_WORD request, U_LONG pctrlblk);
static U_WORD OutputIOCTL(S_WORD request, U_LONG pctrlblk);
static U_LONG RedToSectors(U_LONG red);
static int AllocIOCTLBuffers(void);
static void DPMI_SimRealInt(U_LONG intr, RegBlock_t *rBlock);
static void *DPMI_AllocRealMem(U_LONG size, U_WORD *segment,
U_WORD *selector);
static void DPMI_FreeRealMem(U_WORD selector);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
int cd_Error;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static int cd_DriveCount;
static int cd_FirstDrive;
static int cd_CurDrive;
static U_WORD cd_Version;
static int cd_FirstTrack;
static int cd_LastTrack;
static int cd_TrackCount;
static U_WORD cd_LeadOutMin;
static U_WORD cd_LeadOutSec;
static U_LONG cd_LeadOutRed;
static U_LONG cd_LeadOutSector;
static U_LONG cd_IOCTLBufferTotal;
static AudioTrack_t cd_AudioTracks[MAX_AUDIO_TRACKS];
static int OkInit = 0;
static RegBlock_t RegBlock;
static struct PlayReq_s { // CD-ROM Play Audio Device Request Struct
U_BYTE headerSize;
U_BYTE subUnitCode;
U_BYTE command; // = DRC_PLAYAUDIO
U_WORD status;
U_BYTE reserved[8];
U_BYTE addressMode;
U_LONG startSector;
U_LONG numberToRead;
} *cd_PlayReq;
static U_WORD cd_PlayReqSeg;
static U_WORD cd_PlayReqSel;
static struct StopReq_s { // CD-ROM Stop Audio Device Request Struct
U_BYTE headerSize;
U_BYTE subUnitCode;
U_BYTE command; // = DRC_STOPAUDIO
U_WORD status;
U_BYTE reserved[8];
} *cd_StopReq;
static U_WORD cd_StopReqSeg;
static U_WORD cd_StopReqSel;
static struct ResumeReq_s { // CD-ROM Resume Audio Device Request Struct
U_BYTE headerSize;
U_BYTE subUnitCode;
U_BYTE command; // = DRC_RESUMEAUDIO
U_WORD status;
U_BYTE reserved[8];
} *cd_ResumeReq;
static U_WORD cd_ResumeReqSeg;
static U_WORD cd_ResumeReqSel;
// IOCTL Input command data buffer structures
static struct IOCTLIn_s { // IOCTL Input Struct
U_BYTE headerSize;
U_BYTE subUnitCode;
U_BYTE command; // = DRC_IOCTLINPUT
U_WORD status;
U_BYTE reserved[8];
U_BYTE mediaDescriptor;
U_LONG ctrlBlkAddr;
U_WORD tranSize;
U_WORD startSector;
U_LONG volPtr;
} *cd_IOCTLIn;
static U_WORD cd_IOCTLInSeg;
static U_WORD cd_IOCTLInSel;
static struct RAddrDevHead_s {
U_BYTE code; // ADRDEVHEAD
U_LONG devHdrAddr; // Address of device header
} *cd_RAddrDevHead;
static U_WORD cd_RAddrDevHeadSeg;
static U_WORD cd_RAddrDevHeadSel;
static struct LocHead_s {
U_BYTE code; // HEADLOCATION
U_BYTE addrMode; // Addressing mode
U_LONG headLocation; // Location of drive head
} *cd_LocHead;
static U_WORD cd_LocHeadSeg;
static U_WORD cd_LocHeadSel;
static struct ErrStat_s {
U_BYTE code; // ERRSTATISTICS
U_BYTE errVal; // Error statistics
} *cd_ErrStat;
static U_WORD cd_ErrStatSeg;
static U_WORD cd_ErrStatSel;
static struct AudChanInfo_s {
U_BYTE code; // AUDIOCHANINFO
U_BYTE inChanOut0; // Input chan(0,1,2,or 3) for output chan 0
U_BYTE volumeOut0; // Volume control (0-0xff) for output chan 0
U_BYTE inChanOut1; // Input chan(0,1,2,or 3) for output chan 1
U_BYTE volumeOut1; // Volume control (0-0xff) for output chan 1
U_BYTE inChanOut2; // Input chan(0,1,2,or 3) for output chan 2
U_BYTE volumeOut2; // Volume control (0-0xff) for output chan 2
U_BYTE inChanOut3; // Input chan(0,1,2,or 3) for output chan 3
U_BYTE volumeOut3; // Volume control (0-0xff) for output chan 3
} *cd_AudChanInfo;
static U_WORD cd_AudChanInfoSeg;
static U_WORD cd_AudChanInfoSel;
static struct RDrvBytes_s {
U_BYTE code; // READDRVBYTES
U_BYTE numBytes; // Number of bytes to read
U_BYTE rBuffer[128]; // Read buffer
} *cd_RDrvBytes;
static U_WORD cd_RDrvBytesSeg;
static U_WORD cd_RDrvBytesSel;
static struct DevStat_s {
U_BYTE code; // DEVICESTATUS
U_LONG devParams; // Device parameters
} *cd_DevStat;
static U_WORD cd_DevStatSeg;
static U_WORD cd_DevStatSel;
static struct SectSize_s {
U_BYTE code; // GETSECTORSIZE
U_BYTE readMode; // Read mode
U_WORD sectorSize; // Sector size
} *cd_SectSize;
static U_WORD cd_SectSizeSeg;
static U_WORD cd_SectSizeSel;
static struct VolSize_s {
U_BYTE code; // GETVOLSIZE
U_LONG volumeSize; // Volume size
} *cd_VolSize;
static U_WORD cd_VolSizeSeg;
static U_WORD cd_VolSizeSel;
static struct MedChng_s {
U_BYTE code; // MEDIACHANGED
U_BYTE changed; // Media byte
} *cd_MedChng;
static U_WORD cd_MedChngSeg;
static U_WORD cd_MedChngSel;
static struct DiskInfo_s {
U_BYTE code; // AUDIODISKINFO
U_BYTE lowTrack; // Lowest track number
U_BYTE highTrack; // Highest track number
U_LONG startLeadOut; // Starting point of the lead-out track
} *cd_DiskInfo;
static U_WORD cd_DiskInfoSeg;
static U_WORD cd_DiskInfoSel;
static struct TrackInfo_s {
U_BYTE code; // AUDIOTRACKINFO
U_BYTE track; // Track number
U_LONG start; // Starting point of the track
U_BYTE ctrlInfo; // Track control information
} *cd_TrackInfo;
static U_WORD cd_TrackInfoSeg;
static U_WORD cd_TrackInfoSel;
static struct QInfo_s {
U_BYTE code; // AUDIOQCHANINFO
U_BYTE control; // CONTROL and ADR byte
U_BYTE tno; // Track number (TNO)
U_BYTE index; // (POINT) or Index(X)
U_BYTE min; // (MIN) Running time within a track
U_BYTE sec; // (SEC) " " " " "
U_BYTE frame; // (FRAME) " " " " "
U_BYTE zero; // (ZERO) " " " " "
U_BYTE aMin; // (AMIN) or (PMIN) Running time on disk
U_BYTE aSec; // (ASEC) or (PSEC) " " " "
U_BYTE aFrame; // (AFRAME) or (PFRAME)" " " "
} *cd_QInfo;
static U_WORD cd_QInfoSeg;
static U_WORD cd_QInfoSel;
static struct SubChanInfo_s {
U_BYTE code; // AUDIOSUBINFO
U_LONG startSectAddr; // Starting sector address
U_LONG transAddr; // Transfer address
U_LONG numSects; // Number of sectors to read
} *cd_SubChanInfo;
static U_WORD cd_SubChanInfoSeg;
static U_WORD cd_SubChanInfoSel;
static struct UPCCode_s {
U_BYTE code; // UPCCODE
U_BYTE control; // CONTROL and ADR byte
U_BYTE upc[7]; // UPC/EAN code
U_BYTE zero; // Zero
U_BYTE aFrame; // Aframe
} *cd_UPCCode;
static U_WORD cd_UPCCodeSeg;
static U_WORD cd_UPCCodeSel;
static struct AudStat_s {
U_BYTE code; // AUDIOSTATUSINFO
U_WORD status; // Audio status bits
U_LONG startPlay; // Starting location of last Play/Resume
U_LONG endPlay; // Ending location for last Play/Resume
} *cd_AudStat;
static U_WORD cd_AudStatSeg;
static U_WORD cd_AudStatSel;
// IOCTL Output command data buffer structures
static struct IOCTLOut_s { // IOCTL Output struct
U_BYTE headerSize;
U_BYTE subUnitCode;
U_BYTE command; // = DRC_IOCTLOUTPUT
U_WORD status;
U_BYTE reserved[8];
U_BYTE mediaDescriptor;
U_LONG ctrlBlkAddr;
U_WORD tranSize;
U_WORD startSector;
U_LONG volPtr;
} *cd_IOCTLOut;
static U_WORD cd_IOCTLOutSeg;
static U_WORD cd_IOCTLOutSel;
static struct Eject_s {
U_BYTE code; // EJECTDISK
} *cd_Eject;
static U_WORD cd_EjectSeg;
static U_WORD cd_EjectSel;
static struct LockDoor_s {
U_BYTE code; // DOORLOCK
U_BYTE lock; // Lock function : 0 = unlock, 1 = lock
} *cd_LockDoor;
static U_WORD cd_LockDoorSeg;
static U_WORD cd_LockDoorSel;
static struct ResetDrv_s {
U_BYTE code; // RESETDRIVE
} *cd_ResetDrv;
static U_WORD cd_ResetDrvSeg;
static U_WORD cd_ResetDrvSel;
static struct AudInfo_s {
U_BYTE code; // AUDIOCHANCONTROL
U_BYTE inChanOut0; // Input chan(0,1,2,or 3) for output chan 0
U_BYTE volumeOut0; // Volume control (0-0xff) for output chan 0
U_BYTE inChanOut1; // Input chan(0,1,2,or 3) for output chan 1
U_BYTE volumeOut1; // Volume control (0-0xff) for output chan 1
U_BYTE inChanOut2; // Input chan(0,1,2,or 3) for output chan 2
U_BYTE volumeOut2; // Volume control (0-0xff) for output chan 2
U_BYTE inChanOut3; // Input chan(0,1,2,or 3) for output chan 3
U_BYTE volumeOut3; // Volume control (0-0xff) for output chan 3
} *cd_AudInfo;
static U_WORD cd_AudInfoSeg;
static U_WORD cd_AudInfoSel;
static struct WDrvBytes_s {
U_BYTE code; // WRITEDEVCONTROL
U_BYTE buf[5]; // Write buffer - size ??
} *cd_WDrvBytes;
static U_WORD cd_WDrvBytesSeg;
static U_WORD cd_WDrvBytesSel;
static struct CloseTray_s {
U_BYTE code; // CLOSETRAY
} *cd_CloseTray;
static U_WORD cd_CloseTraySeg;
static U_WORD cd_CloseTraySel;
static U_WORD InCtrlBlkSize[16] = {
0x05, 0x06, 0x00, 0x00,
0x09, 0x82, 0x05, 0x04,
0x05, 0x02, 0x07, 0x07,
0x0b, 0x0d, 0x0b, 0x0b
};
static U_WORD OutCtrlBlkSize[6] = {
0x01, 0x02,
0x01, 0x09,
0x06, 0x01
};
// Structures for allocating conventional memory
static DOSChunk_t DOSChunks[] = {
{
sizeof(struct PlayReq_s),
&cd_PlayReq, &cd_PlayReqSeg, &cd_PlayReqSel
},
{
sizeof(struct StopReq_s),
&cd_StopReq, &cd_StopReqSeg, &cd_StopReqSel
},
{
sizeof(struct ResumeReq_s),
&cd_ResumeReq, &cd_ResumeReqSeg, &cd_ResumeReqSel
},
{
sizeof(struct IOCTLOut_s),
&cd_IOCTLOut, &cd_IOCTLOutSeg, &cd_IOCTLOutSel
},
{
sizeof(struct Eject_s),
&cd_Eject, &cd_EjectSeg, &cd_EjectSel
},
{
sizeof(struct LockDoor_s),
&cd_LockDoor, &cd_LockDoorSeg, &cd_LockDoorSel
},
{
sizeof(struct ResetDrv_s),
&cd_ResetDrv, &cd_ResetDrvSeg, &cd_ResetDrvSel
},
{
sizeof(struct AudInfo_s),
&cd_AudInfo, &cd_AudInfoSeg, &cd_AudInfoSel
},
{
sizeof(struct WDrvBytes_s),
&cd_WDrvBytes, &cd_WDrvBytesSeg, &cd_WDrvBytesSel
},
{
sizeof(struct CloseTray_s),
&cd_CloseTray, &cd_CloseTraySeg, &cd_CloseTraySel
},
{
sizeof(struct IOCTLIn_s),
&cd_IOCTLIn, &cd_IOCTLInSeg, &cd_IOCTLInSel
},
{
sizeof(struct RAddrDevHead_s),
&cd_RAddrDevHead, &cd_RAddrDevHeadSeg, &cd_RAddrDevHeadSel
},
{
sizeof(struct LocHead_s),
&cd_LocHead, &cd_LocHeadSeg, &cd_LocHeadSel
},
{
sizeof(struct ErrStat_s),
&cd_ErrStat, &cd_ErrStatSeg, &cd_ErrStatSel
},
{
sizeof(struct AudChanInfo_s),
&cd_AudChanInfo, &cd_AudChanInfoSeg, &cd_AudChanInfoSel
},
{
sizeof(struct RDrvBytes_s),
&cd_RDrvBytes, &cd_RDrvBytesSeg, &cd_RDrvBytesSel
},
{
sizeof(struct DevStat_s),
&cd_DevStat, &cd_DevStatSeg, &cd_DevStatSel
},
{
sizeof(struct SectSize_s),
&cd_SectSize, &cd_SectSizeSeg, &cd_SectSizeSel
},
{
sizeof(struct VolSize_s),
&cd_VolSize, &cd_VolSizeSeg, &cd_VolSizeSel
},
{
sizeof(struct MedChng_s),
&cd_MedChng, &cd_MedChngSeg, &cd_MedChngSel
},
{
sizeof(struct DiskInfo_s),
&cd_DiskInfo, &cd_DiskInfoSeg, &cd_DiskInfoSel
},
{
sizeof(struct TrackInfo_s),
&cd_TrackInfo, &cd_TrackInfoSeg, &cd_TrackInfoSel
},
{
sizeof(struct QInfo_s),
&cd_QInfo, &cd_QInfoSeg, &cd_QInfoSel
},
{
sizeof(struct SubChanInfo_s),
&cd_SubChanInfo, &cd_SubChanInfoSeg, &cd_SubChanInfoSel
},
{
sizeof(struct UPCCode_s),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -