『楼 主』:
cd-rom驱动的源代码(未测试)
/* CD-ROM low level driver 0.00a
/* 80x86-version
/*
/* Written by V.M.G.van Acht
/* (c) 1998 by Octagone
/*
*/
#include "stdio.h"
/* prototypes */
void Wait (unsigned int count);
unsigned int ReadIDEReg (unsigned int regnum);
void WriteIDEReg (unsigned int regnum,unsigned int data);
int WriteIDECommand (unsigned int *data,unsigned int devnum);
int ReadIDEData (unsigned int *data,unsigned int len);
int WriteATAPICommand(unsigned char *data,unsigned int devnum,unsigned int maxlen);
int ReadATAPIData (unsigned char *data,unsigned int len);
int WriteATAPIData (unsigned char *data,unsigned int len);
struct structATAPIError ATAPIError (unsigned char devnum);
int PlayAudio (unsigned long startsect,unsigned long endsect,unsigned int devnum);
int StopAudio (unsigned int devnum);
int PauseAudio (unsigned int OnOff,unsigned int devnum);
int SetCDSpeed (unsigned int speed,unsigned int devnum);
unsigned long LBA2MSF (unsigned long LBA);
unsigned long MSF2LBA (unsigned long MSF);
void PrintMSF (unsigned long MSF,int flag);
int ReadCDSector (unsigned long sectnum,unsigned char *data,unsigned int len,unsigned int devnum);
void PrintText (unsigned int *data,unsigned int len);
void PrintFileName (unsigned char *data,unsigned char DOSJolietRomeo);
int ReadTOC (unsigned char *data,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum);
int ReadISOHdr (unsigned long sector,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum);
void ResetInquiry (unsigned long *DirTable,unsigned int devnum);
unsigned int SearchDir (unsigned long *DirTable);
int Inquiry (unsigned long *DirTable,unsigned char *SourceName,unsigned char *data,unsigned int devnum);
int ChangeDirectory (unsigned long *DirTable,unsigned char *SourceName,unsigned int devnum);
int ChangeDirectoryUp(unsigned long *DirTable,unsigned int devnum);
int OpenFile (unsigned long *DirTable,unsigned char *SourceName,unsigned char *FilePointer,unsigned int devnum);
int ReadFileBytes (unsigned char *FilePointer,unsigned int length,unsigned char *data);
int NameMatch (unsigned char *SourceName,unsigned char *CheckName,unsigned char DOSJolietRomeo);
void CopyBytes (unsigned char *source,unsigned char *dest,unsigned int len);
unsigned long Char2Long (unsigned char *bytes);
unsigned int Char2Int (unsigned char *bytes);
void Int2Char (unsigned int value,unsigned char *bytes);
void Long2Char (unsigned long value,unsigned char *bytes);
unsigned long Char2LongMSBLSB (unsigned char *bytes);
unsigned int Char2IntMSBLSB (unsigned char *bytes);
void Int2CharMSBLSB (unsigned int value,unsigned char *bytes);
void Long2CharMSBLSB (unsigned long value,unsigned char *bytes);
/* structures */
struct structFileTime
{
unsigned char Year;
unsigned char Month;
unsigned char Day;
unsigned char Hour;
unsigned char Minute;
unsigned char Second;
signed char Greenwich;
};
struct structHdrTime
{
unsigned char Year[4];
unsigned char Month[2];
unsigned char Day[2];
unsigned char Hour[2];
unsigned char Minute[2];
unsigned char Second[2];
unsigned char Hundredth[2];
char Greenwich;
};
struct structDirRecord
{
unsigned char RecordLen;
unsigned char ExtAttributeLen;
unsigned long LocationExtent;
unsigned long DataLen;
struct structFileTime DateTime;
unsigned char FileFlags;
unsigned char FileUnitSize;
unsigned char InterleaveGapSize;
unsigned int VolumeSequenceNumber;
unsigned char FileIdentifierLen;
unsigned char FileIdentifier[256];
};
struct structISOHdr
{
unsigned char StructureVersion;
unsigned long VolumeSpaceSize;
unsigned int VolumeSetSize;
unsigned int VolumeSequenceNumber;
unsigned int LogicalBlockSize;
unsigned long PathTableSize;
unsigned long LocationLPathTable;
unsigned long LocationOptionLPathTable;
unsigned long LocationMPathTable;
unsigned long LocationOptionMPathTable;
struct structDirRecord RootDir;
unsigned char BootSystemIdentifier[32];
unsigned char BootIdentifier[32];
unsigned char SystemIdentifier[32];
unsigned char VolumeIdentifier[32];
unsigned char VolumeSetIdentifier[128];
unsigned char PublisherIdentifier[128];
unsigned char PreparerIdentifier[128];
unsigned char ApplicationIdentifier[128];
unsigned char CopyrightIdentifier[37];
unsigned char AbstractIdentifier[37];
unsigned char BibliographicIdentifier[37];
struct structHdrTime CreationDateTime;
struct structHdrTime ModificationDateTime;
struct structHdrTime ExpirationDateTime;
struct structHdrTime EffectiveDateTime;
unsigned char DOSJolietRomeo; /* 0x00=DOS
0x40=Joliet UCS-2 level 1
0x43=Joliet UCS-2 level 2
0x45=Joliet UCS-2 level 3
*/
};
struct structCache
{
unsigned char DeviceNumber;
unsigned long SectorNumber;
unsigned char SectorCount;
unsigned char *MemoryLocation;
};
struct structATAPIErrorText
{
unsigned char ErrorNumber;
unsigned char ErrorSubNumber;
unsigned char SolutionNumber;
/* 0=no solution presented
1=do not consider as error
2=continue
3=retry
4=reset & retry
5=fail & continu
6=user intervention & retry
7=fail, user intervention & continue
8=ask user
9=abort
ff=software failure
*/
unsigned char SolutionSubNumber;
/* Solutionnumber.SolutionSubNumber
0.
1.
2.
3.
4.
5.0=fail & continu (on next LogicalBlock)
5.1=fail & continu (on next LogicalSector)
5.2=fail & continu (on next file)
6.
7.
8.
9.
ff.0=ATAPI device failure
ff.1=Host failure
*/
unsigned char Text[25];
};
struct structATAPIError
{
unsigned char Flag;
/* Flag 76543210
xxxxxxx0=no error
xxxxxxx1=error
xxxxxx0x=pointer valid
xxxxxx1x=pointer not valid
xxxxx0xx=sense key valid
xxxxx1xx=sense key not valid
xxxx0xxx=current error
xxxx1xxx=deferred error
Pointer to ErrorText
*/
unsigned char SenseKey;
unsigned char AdditionalSenseKey;
unsigned char AdditionalSenseKeyQualifier;
unsigned char SolutionNumber;
unsigned char SolutionSubNumber;
struct structATAPIErrorText *Text;
};
struct structCDPosition
{
unsigned long Absolute;
unsigned long Relative;
unsigned char Track;
unsigned char Index;
};
struct structCDNumber
{
int Flag; /* 0:number=valid
1:number=not valid
-1:hardware error */
unsigned char Number[14];
};
/* declarations */
const
unsigned int IDEport=0X170, /* IDE port 0=0x1F0, 1=0x170 */
IDERegData=0, /* number of IDE registers */
IDERegError=1,
IDERegFeature=1,
IDERegSectCount=2,
IDERegSectNum=3,
IDERegCylLow=4,
IDERegCylHigh=5,
IDERegDevHead=6,
IDERegStatus=7,
IDERegCommand=7,
IDERegAltStatus=14,
IDERegAdres=15;
const
struct structATAPIErrorText ATAPIErrorText[]=
{
{0x00,0x00,0,0,"No additional info "},
{0x00,0x11,1,0,"Audio play in progress "},
{0x00,0x12,1,0,"Audio play paused "},
{0x00,0x13,1,0,"Audio play completed "},
{0x00,0x14,9,0,"Audio play error "},
{0x00,0x15,1,0,"No audio play status "},
{0x01,0x00,9,0,"Mechanical error "},
{0x02,0x00,0,0,"No seek complete "},
{0x04,0x00,8,0,"Not ready "},
{0x04,0x01,1,0,"Not ready, in progress.."},
{0x04,0x02,4,0,"Not ready, reinitialize "},
{0x04,0x03,6,0,"Not ready, manual interv"},
{0x04,0x04,1,0,"Not ready, formatting "},
{0x05,0x00,0,0,"No response to selection"},
{0x05,0x01,9,0,"Load/eject failure "},
{0x06,0x00,9,0,"No reference position "},
{0x08,0x00,9,0,"Communication failure "},
{0x08,0x01,9,0,"Communication timed out "},
{0x08,0x02,9,0,"Communication bad parity"},
{0x09,0x00,3,0,"Tracking error "},
{0x09,0x01,8,0,"Tracking servo failure "},
{0x09,0x02,8,0,"Focus servo failure "},
{0x09,0x03,8,0,"Spindle servo failure "},
{0x11,0x00,3,0,"Unrecovered read error "},
{0x11,0x06,3,0,"CIRC unrecovered error "},
{0x15,0x00,3,0,"Random position error "},
{0x15,0x01,8,0,"Mechanical error "},
{0x15,0x02,3,0,"Random position error "},
{0x17,0x00,1,0,"Recovered, no correction"},
{0x17,0x01,1,0,"Recovered, retries "},
{0x17,0x02,1,0,"Recovered, + head offset"},
{0x17,0x03,1,0,"Recovered, - head offset"},
{0x17,0x04,1,0,"Recovered, retries/CIRC "},
{0x17,0x05,1,0,"Recovered, previous ID "},
{0x18,0x00,1,0,"Recovered, correction "},
{0x18,0x01,1,0,"Recovered, reties/correc"},
{0x18,0x02,1,0,"Recovered, auto realloc "},
{0x18,0x03,1,0,"Recovered, CIRC "},
{0x18,0x04,1,0,"Recovered, L-EC "},
{0x1A,0x00,0xFF,1,"Bad parameterlist length"},
{0x20,0x00,0xFF,1,"Invalid command "},
{0x21,0x00,0xFF,1,"Bad logical block number"},
{0x24,0x00,0xFF,1,"Invalid field in packet "},
{0x25,0x00,0,0,"No logical unit support "},
{0x26,0x00,0xFF,1,"Invalid field in paramet"},
{0x26,0x01,0xFF,1,"Parameter not supported "},
{0x26,0x02,0xFF,1,"Bad parameter value "},
{0x28,0x00,0,0,"Medium may have changed "},
{0x29,0x00,1,0,"Reset occured "},
{0x2A,0x00,1,0,"Parameters changed "},
{0x2A,0x01,1,0,"Mode parameters changed "},
{0x30,0x00,8,0,"Incompatible medium "},
{0x30,0x01,8,0,"Unknown format medium "},
{0x30,0x02,8,0,"Incompatible format "},
{0x39,0x00,9,0,"No saving support "},
{0x3A,0x00,1,0,"No medium "},
{0x3A,0x01,1,0,"No medium, tray closed "},
{0x3A,0x02,1,0,"No medium, tray opened "},
{0x3E,0x00,1,0,"Not self-configured yet "},
{0x3F,0x00,1,0,"Operate condition change"},
{0x3F,0x01,1,0,"Microcode changed "},
{0x3F,0x03,1,0,"Inquiry data changed "},
{0x40,0xFF,0xFF,0,"Self test failed "},
{0x44,0x00,0xFF,0,"Internal error "},
{0x4C,0x00,0xFF,0,"Failed self-config "},
{0x4E,0x00,0xFF,1,"Overlap command attempt "},
{0x53,0x00,9,0,"Load/eject failure "},
{0x53,0x02,0,0,"Medium removal prevented"},
{0x57,0x00,8,0,"TOC load error "},
{0x5A,0x00,0,0,"Operator request "},
{0x5A,0x01,0,0,"Medium removal request "},
{0x63,0x00,0xFF,1,"End of user area error "},
{0x64,0x00,0xFF,1,"Illegal track mode "},
{0xB9,0x00,0,0,"Audio play aborted "},
{0xBF,0x00,3,0,"Loss of streaming "},
{0xFF,0xFF,0,0," "}
};
/* 123456789012345678901234567890
/* global variables */
unsigned int IDENop [6] ={0,0,0,0,0xA0,0X00},
IDEATAPIReset [6] ={0,0,0,0,0XA0,0X08},
IDEDiagnostic [6] ={0,0,0,0,0XA0,0X90},
IDEATAPIPacket[6] ={0,0,0,0,0XA0,0XA0},
IDEATAPIIdent [6] ={0,0,0,0,0XA0,0XA1},
IDEStandbyImm [6] ={0,0,0,0,0XA0,0XE0},
IDEIdleImm [6] ={0,0,0,0,0XA0,0XE1},
IDECheckpower [6] ={0,0,0,0,0XA0,0XE5},
IDESleep [6] ={0,0,0,0,0XA0,0XE6},
IDESetFeatures[6] ={0,0,0,0,0XA0,0XEF};
unsigned char
ATAPIRequestSense[12]={0X03,0,0,0,18,0,0,0,0,0,0,0},
ATAPIStartStopUnit[12]={0X1B,1,0,0,0,0,0,0,0,0,0,0},
ATAPIRead10 [12]={0X28,0,0,0,0,0,0,0,0,0,0,0},
ATAPIReadSubChan1[12]={0X42,0,0x40,1,0,0,0,0,16,0,0,0},
ATAPIReadSubChan2[12]={0x42,0,0x40,2,0,0,0,0,24,0,0,0},
ATAPIReadSubChan3[12]={0x42,0,0x40,3,0,0,0,0,24,0,0,0},
ATAPIReadTOC [12]={0X43,0,0,0,0,0,0,0X03,0X24,0,0,0},
ATAPIPlayAudioMSF[12]={0X47,0,0,0,0,0,0,0,0,0,0,0},
ATAPIPauseAudio [12]={0X4B,0,0,0,0,0,0,0,0,0,0,0},
ATAPIStopAudio [12]={0X4E,0,0,0,0,0,0,0,0,0,0,0},
ATAPISetSpeed [12]={0XBB,0,0,0,0,0,0,0,0,0,0,0};
struct structCache SectorCache; /* SectorBuffer Cache */
unsigned int Device0Data[256], /* Table for device data for dev0 */
Device1Data[256]; /* Table for device data for dev1 */
unsigned char
Device0TOC[804], /* Table for device 0 TOC */
Device1TOC[804], /* Table for device 1 TOC */
SectorBuf[2048]; /* Temporary buffer */
struct structISOHdr Device0ISOHdr; /*Table for device 0 ISO header */
struct structISOHdr Device1ISOHdr; /*Table for device 1 ISO header */
unsigned long
Device0DirTable[36], /* Table with Sectornumbers of Dirs
WARNING: SECTOR numbers not Logical Block Numbers !!!
+32=current sectornumber current dir
+33=current length current dir
+34=current byte counter current dir
+35=DOSJolietRomeo
+36=Logical Block Size
*/
Device1DirTable[36]; /* Table with Sectornumbers of Dirs */
unsigned int NumDevice;
/************************************************************************/
void Test (unsigned char *ATAPICommand)
{
unsigned int i;
for (i=0;i<12;i++)
{
printf("%X-",*(ATAPICommand+i));
}
}
void PrintLong (unsigned long var)
{
printf("%X",var>>16);
printf("%X",var&0xFFFF);
}
void Wait (unsigned int counter)
/* Wait
*/
{
unsigned int i;
while (counter>0)
{counter--;
i=0Xffff;
while (i!=0)
{i--;}
}
}
unsigned char WaitKey ()
/* Wait for a key press
in: nothing
out: key
*/
{
unsigned int i;
printf("\nPress any key to continu...");
while ((i=getch())==EOF)
{}
return(i);
}
unsigned int ReadIDEReg (unsigned int regnum)
/* Read value of IDE register (LOW-LEVEL)
in: number of register: 0=data register (16 bit)
1=error register
2=sector count register
3=sector number register
4=cylinder register (LSB)
5=cylinder register (MSB)
6=drive/head register
7=status register
8=Not used
9=not used
10=not used
11=not used
12=not used
13=not used
14=alternate status register
15=adres register
out:value
*/
{
unsigned int i,j;
if (regnum>=8) {i=IDEport+regnum+0X1F8;}
else {i=IDEport+regnum;}
asm {
MOV DX,(i)
IN AX,DX
MOV (j),AX
}
return(j);
}
void WriteIDEReg (unsigned int regnum, unsigned int data)
/* Write value to IDE register (LOW-LEVEL)
in: number of register: 0=data register (16 bit)
1=feature register
2=sector count register
3=sector number register
4=cylinder register (LSB)
5=cylinder register (MSB)
6=drive/head register
7=command register
8=Not used
9=not used
10=not used
11=not used
12=not used
13=not used
14=control register
15=not used
data
*/
{
unsigned int i,j;
if (regnum>=8) {i=IDEport+regnum+0X1F8;}
else {i=IDEport+regnum;}
j=data;
asm {
MOV DX,(i)
MOV AX,(j)
OUT DX,AX
}
}
int WriteIDECommand (unsigned int *data,unsigned int devnum)
/* Write IDE Command
in: data = pointer to 6 unsigned int with values for reg 2-reg7
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
unsigned int i,j;
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
WriteIDEReg(IDERegDevHead,(*(data+4)+(devnum<<4)));
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0XC0)!=0X40);
for (i=0;i<4;i++)
{
WriteIDEReg(i+2,*(data+i));
}
WriteIDEReg(IDERegCommand,*(data+5));
return(0);
}
int ReadIDEData (unsigned int *data,unsigned int len)
/* Read IDE (16 bit) data from data-register
in: *data = pointer where data is to be located
len = maximum number of words
out: -1 = error
0 = OK
*/
{
unsigned int i,j;
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
if ((ReadIDEReg(7)&0x01)!=0)
{
return(-1);};
}
while ((ReadIDEReg(7)&0x80)!=0);
if ((ReadIDEReg(7)&0x08)!=0x08)
{
return(-1);
}
while (len!=0)
{
*data=ReadIDEReg(0);
len--;
data++;
}
return(0);
}
int WriteATAPICommand(unsigned char *data,unsigned int devnum,unsigned int maxlen)
/* Write ATAPI Command
in: *data = pointer to unsigned char array [12] with command arguments
MaxLen = maximum number of bytes to be transfered in 1 time (0xffff allowed)
DriveNum = drive number 0/1
out: -1 = error
0 = OK
*/
{
unsigned int i;
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
WriteIDEReg(IDERegDevHead,(0XA0+(devnum<<4)));
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
WriteIDEReg(IDERegCylLow,maxlen&0XFF);
WriteIDEReg(IDERegCylHigh,maxlen>>8);
WriteIDEReg(IDERegCommand,0XA0);
i=0;
do
{
if (i==0XFFFF)
{
return(-1);
}
if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
{
return(-1);
}
}
while ((ReadIDEReg(IDERegStatus)&0x08)==0);
for (i=1;i<=6;i++)
{
WriteIDEReg(IDERegData,*(data+0)+(*(data+1)<<8));
data=data+2;
}
return(0);
}
int ReadATAPIData (unsigned char *data,unsigned int len)
/* Read ATAPI data from data-register to CHAR array
in: *data = pointer to unsigned char array where data is to be located
len = number of WORDS
out: -1 = error
0 = OK
*/
{
unsigned int i,j,k;
i=0;
do
{
if (i==0XFFFF)
{
return(len);
}
if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0x08)==0);
do
{
k=(ReadIDEReg(4)&0XFF)+((ReadIDEReg(5)&0XFF)<<8);
do
{
if (len==0)
{
return(0);
}
i=ReadIDEReg(IDERegData);
*data=i&0xff;
data++;
*data=i>>8;
len--;
k--;
data++;
}
while (k!=0);
}
while ((ReadIDEReg(IDERegStatus)&0X08)!=0);
return(0);
}
int WriteATAPIData (unsigned char *data,unsigned int len)
/* Write ATAPI data to data-register to CHAR array
in: *data = pointer to unsigned char array with data
len = number of WORDS to write
out: -1 = error
0 = OK
*/
{
unsigned int i,j,k;
i=0;
do
{
if (i==0)
{
return(len);
}
if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
{
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0x08)==0);
do
{
k=(ReadIDEReg(4)&0XFF)+((ReadIDEReg(5)&0XFF)<<8);
do
{
if (len==0)
{
return(0);
}
WriteIDEReg(IDERegData,*data+(*(data+1)<<8));
len--;
k--;
data=data+2;
}
while (k!=0);
}
while ((ReadIDEReg(IDERegStatus)&0X08)!=0);
return(0);
}
struct structATAPIError ATAPIError (unsigned char devnum)
/* Check if there is an ATAPI-error pending
in: devnum = device number 0/1
out: structATAPIError = Flag 76543210
xxxxxxx0=no error
xxxxxxx1=error
xxxxxx0x=pointer valid
xxxxxx1x=pointer not valid
xxxxx0xx=sense key valid
xxxxx1xx=sense key not valid
xxxx0xxx=current error
xxxx1xxx=deferred error
SenseKey
AdditionalSenseKey
AdditionalSenseKeyQualifier
Pointer to ErrorText
*/
{
unsigned int i;
unsigned char temp[256],*j;
struct structATAPIError ReturnValue;
ReturnValue.Flag=0x07;
i=0;
do
{
if (i==0XFFFF)
{
return(ReturnValue);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
WriteIDEReg(IDERegDevHead,(0XA0+(devnum<<4)));
i=0;
do
{
if (i==0XFFFF)
{
return(ReturnValue);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
ReturnValue.Flag=ReturnValue.Flag&(ReadIDEReg(IDERegStatus)&0x01);
WriteATAPICommand(ATAPIRequestSense,devnum,128);
if (ReadATAPIData(temp,128)==0)
{
ReturnValue.Flag=ReturnValue.Flag&0xfb;
ReturnValue.Flag=ReturnValue.Flag|(*(temp+2)>>2);
ReturnValue.SenseKey=*(temp+2)&0x0f;
ReturnValue.AdditionalSenseKey=*(temp+12);
ReturnValue.AdditionalSenseKeyQualifier=*(temp+13);
for (j=ATAPIErrorText;((*j!=0xff) || (*(j+1)!=0xff));j=j+29)
{
if ((*j==ReturnValue.AdditionalSenseKey) && (*(j+1)==ReturnValue.AdditionalSenseKeyQualifier))
{
ReturnValue.Flag=ReturnValue.Flag&0xfd;
ReturnValue.SolutionNumber=*(j+2);
ReturnValue.SolutionSubNumber=*(j+3);
ReturnValue.Text=j+4;
return(ReturnValue);
}
}
}
return(ReturnValue);
}
int PlayAudio (unsigned long startsect,unsigned long endsect,unsigned int devnum)
/* Play Audio
in: startsect = start sector (logical block)
endsect = end sector (logical block)
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
unsigned long i;
i=LBA2MSF(startsect);
ATAPIPlayAudioMSF[3] = (i&0x00ff0000)>>16;
ATAPIPlayAudioMSF[4] = (i&0x0000ff00)>>8;
ATAPIPlayAudioMSF[5] = (i&0x000000ff);
i=LBA2MSF(endsect);
ATAPIPlayAudioMSF[6] = (i&0x00ff0000)>>16;
ATAPIPlayAudioMSF[7] = (i&0x0000ff00)>>8;
ATAPIPlayAudioMSF[8] = (i&0x000000ff);
return(WriteATAPICommand(ATAPIPlayAudioMSF,devnum,0XFFFF));
}
int StopAudio (unsigned int devnum)
/* Stop Audio
in: devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
return(WriteATAPICommand(ATAPIStopAudio,devnum,0XFFFF));
}
int PauseAudio (unsigned int OnOff,unsigned int devnum)
/* Pause Audio
in: OnOff 0 = pause
1 = resume
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
ATAPIPauseAudio[8]=OnOff&0x01;
return(WriteATAPICommand(ATAPIPauseAudio,devnum,0XFFFF));
}
int SetCDSpeed (unsigned int speed,unsigned int devnum)
/* Set CD Speed
in: speed = speed in Kbyte/sec 0xFFFF = fastest
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
Int2CharMSBLSB(speed,ATAPISetSpeed+2);
return(WriteATAPICommand(ATAPISetSpeed,devnum,0XFFFF));
}
int StartStopUnit (unsigned int action,unsigned int devnum)
/* Start CD spindle servo, Stop CD spindle servo, Open tray, Close tray
in: action 0 = Stop spindle servo
1 = Start spindle servo
2 = Open tray
3 = Close tray
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
ATAPIStartStopUnit[4]=action&0x03;
return(WriteATAPICommand(ATAPIStartStopUnit,devnum,0XFFFF));
}
struct structCDPosition ReadCDPosition (unsigned int devnum)
/* Read from Sub-channel data current audio-play-position
in: devnum = device number 0/1
out: structCDPos,
if .Absolute=0xffffffff then error
*/
{
unsigned char temp[16];
struct structCDPosition CDPos;
CDPos.Absolute=0xffffffff;
if (WriteATAPICommand(ATAPIReadSubChan1,devnum,16)!=0)
{
return(CDPos);
}
if (ReadATAPIData(temp,8)!=0)
{
return(CDPos);
}
CDPos.Absolute =Char2LongMSBLSB(temp+8);
CDPos.Relative =Char2LongMSBLSB(temp+12);
CDPos.Track =*(temp+6);
CDPos.Index =*(temp+7);
return(CDPos);
}
struct structCDNumber ReadUPC (unsigned int devnum)
/* Read from Sub-channel data current Media Catalog Number
in: devnum = device number 0/1
out: structCDNumber,
if .Flag=-1 then hardware error
*/
{
unsigned int i;
unsigned char temp[24];
struct structCDNumber CDNum;
CDNum.Flag=-1;
if (WriteATAPICommand(ATAPIReadSubChan2,devnum,24)!=0)
{
return(CDNum);
}
if (ReadATAPIData(temp,12)!=0)
{
return(CDNum);
}
CDNum.Flag=(*(temp+8)>>7)^0x01;
for (i=0;i<=13;i++)
{
CDNum.Number[i]=*(temp+i+9);
}
return(CDNum);
}
struct structCDNumber ReadISRC (unsigned int track,unsigned int devnum)
/* Read from Sub-channel data track international standard recording code
in: track = tracknumber
devnum = device number 0/1
out: structCDNumber,
if .Flag=-1 then hardware error
*/
{
unsigned int i;
unsigned char temp[24];
struct structCDNumber CDNum;
CDNum.Flag=-1;
ATAPIReadSubChan3[6]=track;
if (WriteATAPICommand(ATAPIReadSubChan3,devnum,24)!=0)
{
return(CDNum);
}
if (ReadATAPIData(temp,12)!=0)
{
return(CDNum);
}
CDNum.Flag=(*(temp+8)>>7)^0x01;
for (i=0;i<=13;i++)
{
CDNum.Number[i]=*(temp+i+9);
}
return(CDNum);
}
unsigned long LBA2MSF (unsigned long LBA)
/* convert LBA to MSF
in: LBA = unsigned long LBA number
out: MSF = unsigned long, bit 0- 7:F
bit 8-15:S
bit16-23:M
*/
{
unsigned long i,j;
LBA=LBA+150;
i=(LBA/4500);
LBA=LBA-(i*4500);
i=i*0x10000;
j=(LBA/75);
LBA=LBA-(j*75);
i=i+(j*0x100)+LBA;
return(i);
}
unsigned long MSF2LBA (unsigned long MSF)
/* convert MSF to LBA
in: MSF = unsigned long MSF, bit 0- 7:F
bit 8-15:S
bit16-23:M
out: LBA
*/
{
unsigned long i;
i=((MSF&0xff0000)>>16)*4500+
((MSF&0x00ff00)>> 8)*75 +
(MSF&0x0000ff);
i=i-150;
return(i);
}
void PrintMSF (unsigned long MSF,int flag)
/* print MSF
in: MSF = unsigned long, bit 0- 7:F
bit 8-15:S
bit16-23:M
flag = 0:print F
!=0:do not print F
*/
{
printf("%.2d", (MSF&0xff0000)>>16);
printf(":%.2d",(MSF&0x00ff00)>>8);
if (flag==0)
{
printf(":%.2d",(MSF&0x0000ff));
}
}
int ReadCDSector (unsigned long sectnum,unsigned char *data,unsigned int sectcount,unsigned int devnum)
/* Read data-sectors from CD
!!!! includes cacheing !!!!
in: sectnum = start sector number to be read
data = pointer to CHAR where data is to be written
sectcount= number of sectors to be read
devnum = device number 0/1
out: 0 = OK
-1 = error
*/
{
unsigned long i;
if ( (SectorCache.DeviceNumber==devnum) &&
(SectorCache.SectorNumber==sectnum) &&
(SectorCache.MemoryLocation==data) &&
(sectcount==1) &&
(SectorCache.SectorCount==1) )
{
return(0);
}
Long2CharMSBLSB(sectnum,ATAPIRead10+2);
Int2CharMSBLSB(sectcount,ATAPIRead10+7);
if (WriteATAPICommand(ATAPIRead10,devnum,0XFFFF)!=0)
{
return(-1);
}
i=0;
do
{
if (i==0x0FFFFFF)
{
printf("Duurt te lang");
return(-1);
}
i++;
}
while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
if (ReadATAPIData(data,sectcount<<10)!=0)
{
return(-1);
}
SectorCache.DeviceNumber=devnum;
SectorCache.SectorNumber=sectnum;
SectorCache.MemoryLocation=data;
SectorCache.SectorCount=sectcount;
return(0);
}
void PrintText (unsigned int *data,unsigned int len)
/* Print ASCII-characters in words
in: *data = pointer to words with 2 ASCII characters in each
len = number of words (=Number of characters/2)
*/
{
unsigned int i;
for (i=0;i<len;i++)
{printf("%c%c",(*(data+i))>>8,(*(data+i))&0xff);};
}
void PrintFileName (unsigned char *data,unsigned char DOSJolietRomeo)
/* Print a filename, DOS 8.3 (ISO9660 extended to 32 characters), Joliet, Romeo
in: *data = pointer to filename. First char gives length
DOSJolietRomeo = DOSJolietRomeo flag
*/
{
unsigned int i;
for (i=1;i<=*(data);)
{
if (DOSJolietRomeo==0)
{
if (*(data+i)==0x3B)
{
return;
}
printf("%c",*(data+i));
i++;
}
else if ( (DOSJolietRomeo==0x40) ||
(DOSJolietRomeo==0x43) ||
(DOSJolietRomeo==0x45) )
{
if ( (*(data+i))==0x00 ||
(*(data+i+1))==0x3B )
{
return;
}
printf("%c",*(data+i+1));
i++;
i++;
}
/* else if hier moet nog Romeo-code staan $#@!$#! */
}
}
int ReadTOC (unsigned char *data,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum)
/* Read TOC of a CD, and ISO9660 data
in: *data = pointer to dataspace (max 804 bytes)
*ISOdata= pointer to ISO-data
devnum = device number
out: -1 = error
0 = OK, no data tracks
1 = OK, 1 track (data track)
>1 = OK, datatracks, more than 1 track (mixed mode?)
*/
{
unsigned int i,datatrack=0;
unsigned long adres;
unsigned char *j;
if (WriteATAPICommand(ATAPIReadTOC,devnum,0XFFFF)!=0)
{
return(-1);
}
if (ReadATAPIData(data,804)!=0)
{
return(-1);
}
for (i=*(data+2);i<=(data+3);i++)
{
if ((*(data+(i-*(data+2))*8+5)&0X0D)==0X04)
{
if (datatrack==0)
{
j=data+(i-*(data+2))*8+8;
adres=(*(j+0)<<24) + (*(j+1)<<16) + (*(j+2)<<8) + (*(j+3));
ReadISOHdr(adres,ISOHdr,DirTable,devnum);
}
datatrack=i;
}
}
return(datatrack);
}
int ReadISOHdr (unsigned long sector,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum)
/* Fill ISOHdr
in: sector = first sector of ISO9660 data-block
data = pointer to where ISOHdr is to be located
devnum = device number 0/1
out: 0 = OK (ISO9660 disc)
-1 = error (not ISO9660 disc)
*/
{
unsigned long cursect;
unsigned int i;
cursect=sector+16;
do
{
ReadCDSector(cursect,SectorBuf,1,devnum);
if (*(SectorBuf+1)!='C' ||
*(SectorBuf+2)!='D' ||
*(SectorBuf+3)!='0' ||
*(SectorBuf+4)!='0' ||
*(SectorBuf+5)!='1' ) {return(-1);}
switch (*(SectorBuf))
{
case 0 :
{
CopyBytes(SectorBuf+7,ISOHdr->BootSystemIdentifier,32);
CopyBytes(SectorBuf+39,ISOHdr->BootIdentifier,32);
break;
}
case 1 :
{
CopyBytes(SectorBuf+8,&ISOHdr->SystemIdentifier,32);
CopyBytes(SectorBuf+40,&ISOHdr->VolumeIdentifier,32);
ISOHdr->VolumeSpaceSize =Char2Long(SectorBuf+80);
ISOHdr->VolumeSetSize =Char2Int(SectorBuf+120);
ISOHdr->VolumeSequenceNumber =Char2Int(SectorBuf+124);
ISOHdr->LogicalBlockSize =Char2Int(SectorBuf+128);
ISOHdr->PathTableSize =Char2Long(SectorBuf+132);
ISOHdr->LocationLPathTable =Char2Long(SectorBuf+140);
ISOHdr->LocationOptionLPathTable=Char2Long(SectorBuf+144);
ISOHdr->LocationMPathTable =Char2Long(SectorBuf+148);
ISOHdr->LocationOptionMPathTable=Char2Long(SectorBuf+152);
ISOHdr->RootDir.RecordLen =*(SectorBuf+156);
ISOHdr->RootDir.ExtAttributeLen=*(SectorBuf+157);
ISOHdr->RootDir.LocationExtent=Char2Long(SectorBuf+158);
ISOHdr->RootDir.DataLen =Char2Long(SectorBuf+166);
CopyBytes(SectorBuf+174,&ISOHdr->RootDir.DateTime,7);
ISOHdr->RootDir.FileFlags =*(SectorBuf+181);
ISOHdr->RootDir.FileUnitSize =*(SectorBuf+182);
ISOHdr->RootDir.InterleaveGapSize=*(SectorBuf+183);
ISOHdr->RootDir.VolumeSequenceNumber=*(SectorBuf+184);
ISOHdr->RootDir.FileIdentifierLen=*(SectorBuf+185);
CopyBytes(SectorBuf+189,&ISOHdr->RootDir.FileIdentifier,1);
CopyBytes(SectorBuf+190,&ISOHdr->VolumeSetIdentifier,128);
CopyBytes(SectorBuf+318,&ISOHdr->PublisherIdentifier,128);
CopyBytes(SectorBuf+446,&ISOHdr->PreparerIdentifier,128);
CopyBytes(SectorBuf+574,&ISOHdr->ApplicationIdentifier,128);
CopyBytes(SectorBuf+702,&ISOHdr->CopyrightIdentifier,37);
CopyBytes(SectorBuf+739,&ISOHdr->AbstractIdentifier,37);
CopyBytes(SectorBuf+776,&ISOHdr->BibliographicIdentifier,37);
CopyBytes(SectorBuf+813,&ISOHdr->CreationDateTime,17);
CopyBytes(SectorBuf+830,&ISOHdr->ModificationDateTime,17);
CopyBytes(SectorBuf+847,&ISOHdr->ExpirationDateTime,17);
CopyBytes(SectorBuf+864,&ISOHdr->EffectiveDateTime,17);
ISOHdr->StructureVersion=*(SectorBuf+881);
ISOHdr->DOSJolietRomeo=0;
break;
}
case 2 :
{
if ((*(SectorBuf+7)&0x01)==0)
{
if ( (*(SectorBuf+88)==0x25) &&
(*(SectorBuf+89)==0x2F) )
{
if ( (*(SectorBuf+90)==0x40) ||
(*(SectorBuf+90)==0x43) ||
(*(SectorBuf+90)==0x45) )
{
CopyBytes(SectorBuf+8,&ISOHdr->SystemIdentifier,32);
CopyBytes(SectorBuf+40,&ISOHdr->VolumeIdentifier,32);
ISOHdr->VolumeSpaceSize =Char2Long(SectorBuf+80);
ISOHdr->VolumeSetSize =Char2Int(SectorBuf+120);
ISOHdr->VolumeSequenceNumber =Char2Int(SectorBuf+124);
ISOHdr->LogicalBlockSize =Char2Int(SectorBuf+128);
ISOHdr->PathTableSize =Char2Long(SectorBuf+132);
ISOHdr->LocationLPathTable =Char2Long(SectorBuf+140);
ISOHdr->LocationOptionLPathTable=Char2Long(SectorBuf+144);
ISOHdr->LocationMPathTable =Char2Long(SectorBuf+148);
ISOHdr->LocationOptionMPathTable=Char2Long(SectorBuf+152);
ISOHdr->RootDir.RecordLen =*(SectorBuf+156);
ISOHdr->RootDir.ExtAttributeLen=*(SectorBuf+157);
ISOHdr->RootDir.LocationExtent=Char2Long(SectorBuf+158);
ISOHdr->RootDir.DataLen =Char2Long(SectorBuf+166);
CopyBytes(SectorBuf+174,&ISOHdr->RootDir.DateTime,7);
ISOHdr->RootDir.FileFlags =*(SectorBuf+181);
ISOHdr->RootDir.FileUnitSize =*(SectorBuf+182);
ISOHdr->RootDir.InterleaveGapSize=*(SectorBuf+183);
ISOHdr->RootDir.VolumeSequenceNumber=*(SectorBuf+184);
ISOHdr->RootDir.FileIdentifierLen=*(SectorBuf+185);
CopyBytes(SectorBuf+189,&ISOHdr->RootDir.FileIdentifier,1);
CopyBytes(SectorBuf+190,&ISOHdr->VolumeSetIdentifier,128);
CopyBytes(SectorBuf+318,&ISOHdr->PublisherIdentifier,128);
CopyBytes(SectorBuf+446,&ISOHdr->PreparerIdentifier,128);
CopyBytes(SectorBuf+574,&ISOHdr->ApplicationIdentifier,128);
CopyBytes(SectorBuf+702,&ISOHdr->CopyrightIdentifier,37);
CopyBytes(SectorBuf+739,&ISOHdr->AbstractIdentifier,37);
CopyBytes(SectorBuf+776,&ISOHdr->BibliographicIdentifier,37);
CopyBytes(SectorBuf+813,&ISOHdr->CreationDateTime,17);
CopyBytes(SectorBuf+830,&ISOHdr->ModificationDateTime,17);
CopyBytes(SectorBuf+847,&ISOHdr->ExpirationDateTime,17);
CopyBytes(SectorBuf+864,&ISOHdr->EffectiveDateTime,17);
ISOHdr->StructureVersion=*(SectorBuf+881);
ISOHdr->DOSJolietRomeo=*(SectorBuf+90);
}
}
}
break;
}
case 3 :
{
break;
}
case 255 :
{
break;
}
default :
{
return(-1);
}
}
cursect++;
}
while (*(SectorBuf)!=255);
for (i=0;i<34;i++)
{
*(DirTable+i)=0;
}
*(DirTable+36)=ISOHdr->LogicalBlockSize;
*(DirTable)=(ISOHdr->RootDir.LocationExtent)/(2048/ *(DirTable+36));
*(DirTable+1)=ISOHdr->RootDir.DataLen;
*(DirTable+35)=ISOHdr->DOSJolietRomeo;
return(0);
}
unsigned int SearchDir (unsigned long *DirTable)
/* Give depth of current directory in DirTable
in: DirTable= pointer to Directory Table
out: integer of directory depth
*/
{
unsigned int i;
i=15;
while (*(DirTable+(i<<1))==0)
{
i--;
}
return(i);
}
void ResetInquiry (unsigned long *DirTable,unsigned int devnum)
/* Reset Inquiry. Give this command, before the FIRST "next inquiry item" command
in: DirTable= pointer to Directory Table
devnum = device number 0/1
*/
{
unsigned int i;
i=SearchDir(DirTable);
*(DirTable+32)=*(DirTable+(i<<1));
*(DirTable+33)=*(DirTable+(i<<1)+1)-68;
*(DirTable+34)=68;
}
int Inquiry (unsigned long *DirTable,unsigned char *SourceName,unsigned char *data,unsigned int devnum)
/* Give next file in inquiry
in: DirTable= pointer to Directory Table
SourceName=Name to look for. Char array terminated with \0
wildcards: ? = any character
* = any number of any characters upto "."
\ = from here on don't care
data = pointer to data area where directory record is loaded
devnum = device number
out: 0 = OK, found
1 = error (not found)
-1 = error (hardware)
*/
{
unsigned long cursect,
curlen,
curbyte;
cursect=*(DirTable+32);
curlen =*(DirTable+33);
curbyte=*(DirTable+34);
while (curlen!=0)
{
if (curbyte==512)
{
curbyte=0;
cursect++;
}
if (ReadCDSector(cursect,SectorBuf,1,devnum)!=0)
{
return(-1);
}
if (*(SectorBuf+curbyte)==0)
{
if (curlen<=(2048-curbyte))
{
*(DirTable+33)=0;
return(1);
}
curlen=curlen-(2048-curbyte);
curbyte=0;
cursect++;
ReadCDSector(cursect,SectorBuf,1,devnum);
}
if (NameMatch(SectorBuf+curbyte+32,SourceName,*(DirTable+35))==0)
{
CopyBytes(SectorBuf+curbyte,data,*(SectorBuf+curbyte));
*(DirTable+32)=cursect;
*(DirTable+33)=curlen-*(SectorBuf+curbyte);
*(DirTable+34)=curbyte+*(SectorBuf+curbyte);
return(0);
}
curlen=curlen-*(SectorBuf+curbyte);
curbyte=curbyte+*(SectorBuf+curbyte);
}
*(DirTable+32)=cursect;
*(DirTable+33)=curlen;
*(DirTable+34)=curbyte;
return(1);
}
int NameMatch (unsigned char *SourceName,unsigned char *CheckName,unsigned char DOSJolietRomeo)
/* Check if SourceName and CheckName are equal. CheckName is allowed to have wildcards
in: SourceName = char pointer to char array to be checked.
FIRST byte L in array is length of name (so length array is L+1)
CheckName = pointer to char ASCIIZ text
wildcards: ? = any character
* = any number of any characters upto "."
\ = from here on don't care
DOSJolietRomeo = 00 = DOS 8.3 filename in Sourcename
40 = Joliet filename in Sourcename, UCS-2 level 1
43 = Joliet filename in Sourcename, UCS-2 level 2
45 = Joliet filename in Sourcename, UCS-2 level 3
out: 0 = OK (equal)
-1 = error (not equal)
*/
{
unsigned int SourceCounter=1,
CheckCounter =0;
do
{
if (*(CheckName+CheckCounter)=='\\')
{
return(0);
}
if ( ((*SourceName - SourceCounter + 1 )==0) ||
( (DOSJolietRomeo==0) && (*(SourceName + SourceCounter)==0x3B) ) ||
( ( (DOSJolietRomeo==0x40) || (DOSJolietRomeo==0x43) || (DOSJolietRomeo==0x45) ) && ( (*(SourceName + SourceCounter)==0x00) && (*(SourceName + SourceCounter)==0x3B) )) )
{
while (*(CheckName+CheckCounter)!=0)
{
if ((*(CheckName+CheckCounter)=='*') ||
(*(CheckName+CheckCounter)=='?') ||
(*(CheckName+CheckCounter)=='.') ||
(*(CheckName+CheckCounter)=='\\') )
{
CheckCounter++;
}
else
{
return(-1);
}
}
return(0);
}
if (*(CheckName+CheckCounter)==0)
{
return(-1);
}
if (*(CheckName+CheckCounter)=='?')
{
CheckCounter++;
if (DOSJolietRomeo==0)
{
SourceCounter++;
}
else if ( (DOSJolietRomeo==0x40) ||
(DOSJolietRomeo==0x43) ||
(DOSJolietRomeo==0x45) )
{
SourceCounter++;
SourceCounter++;
}
/* else if .... hier moet nog een check voor Romeo %$#@#$@!%$ */
}
else if (*(CheckName+CheckCounter)=='*')
{
if (DOSJolietRomeo==0)
{
while (*(SourceName+SourceCounter)!='.')
{
SourceCounter++;
if ((*SourceName - SourceCounter) == 0)
{
return(0);
}
}
CheckCounter++;
}
else if ( (DOSJolietRomeo==0x40) ||
(DOSJolietRomeo==0x43) ||
(DOSJolietRomeo==0x45) )
{
while (*(SourceName+SourceCounter)!='.')
{
SourceCounter++;
SourceCounter++;
if ((*SourceName - SourceCounter) == 0)
{
return(0);
}
}
CheckCounter++;
}
/* else if ..... hier moet nog een check voor Romeo !$%#@!$#@ */
}
else
{
if (DOSJolietRomeo==0)
{
if (*(SourceName+SourceCounter)!= *(CheckName+CheckCounter))
{
return (-1);
}
else
{
SourceCounter++;
CheckCounter++;
}
}
else if ( (DOSJolietRomeo==0x40) ||
(DOSJolietRomeo==0x43) ||
(DOSJolietRomeo==0x45) )
{
if (*(SourceName+SourceCounter+1)!= *(CheckName+CheckCounter))
{
return (-1);
}
else
{
SourceCounter++;
SourceCounter++;
CheckCounter++;
}
}
/* else if hier moet nog een test voor Romeo */
}
}
while (1);
}
int ChangeDirectory (unsigned long *DirTable,unsigned char *SourceName,unsigned int devnum)
/* Change active directory
in: DirTable= pointer to Directory Table
SourceName=Name to look for. Char array terminated with \0
wildcards: ? = any character
* = any number of any characters upto "."
\ = from here on don't care
devnum = device number
out: 0 = OK, found
1 = error (not found)
2 = error (too deep (>16))
-1 = error (hardware)
*/
{
unsigned char temp[256];
unsigned int i;
ResetInquiry(DirTable,devnum);
while (1)
{
i=Inquiry(DirTable,SourceName,temp,devnum);
if (i!=0)
{
return(i);
}
if ((*(temp+25)&0x02)==0x02)
{
i=SearchDir(DirTable);
if (i==15)
{
return(2);
}
i++;
*(DirTable+(i<<1))=(Char2Long(temp+2))/(2048/ *(DirTable+36));
*(DirTable+(i<<1)+1)=Char2Long(temp+10);
ResetInquiry(DirTable,devnum);
return(0);
}
}
}
int ChangeDirectoryUp(unsigned long *DirTable,unsigned int devnum)
/* Change active directory, one brach up.
in: DirTable= pointer to Directory Table
devnum = device number
out: 0 = OK, found
1 = error (allready in root)
*/
{
unsigned int i;
i=SearchDir(DirTable);
if (i==0)
{
return(1);
}
*(DirTable+(i<<1))=0;
*(DirTable+(i<<1)+1)=0;
ResetInquiry(DirTable,devnum);
return(0);
}
int OpenFile (unsigned long *DirTable,unsigned char *SourceName,unsigned char *FilePointer,unsigned int devnum)
/* Open File
in: DirTable= pointer to Directory Table
SourceName=Name to look for. Char array terminated with \0
wildcards: ? = any character
* = any number of any characters upto "."
\ = from here on don't care
FilePointer=Char array (274 bytes)
+0 = directory entry (256)
+256 = current Logical Block (4)
+260 = current File length (4)
+264 = current byte counter (4)
+268 = devnum (1)
+269 = Logical Block Length (4)
+273 = current File Unit Size counter (1)
devnum = device number
out: 0 = OK, found
1 = error (not found)
-1 = error (hardware)
*/
{
unsigned int i;
ResetInquiry(DirTable,devnum);
while (1)
{
i=Inquiry(DirTable,SourceName,FilePointer,devnum);
if (i!=0)
{
return(i);
}
if ((*(FilePointer+25)&0x02)!=0x02)
{
CopyBytes(FilePointer+2,FilePointer+256,4);
CopyBytes(FilePointer+10,FilePointer+260,4);
Long2Char(0,FilePointer+264);
*(FilePointer+268)=devnum;
Long2Char(*(DirTable+36),FilePointer+269);
*(FilePointer+273)=1;
return(0);
}
}
}
int ReadFileBytes (unsigned char *FilePointer,unsigned int length,unsigned char *data)
/* Read from File, in bytes
in: FilePointer= pointer to file info table
length = number of bytes to be read
data = pointer to where data is to be located
out: 0 = OK
<>0 = error (EOF) number is bytes read
-1 = error (hardware)
*/
{
unsigned long curLB,
curbyte,
curlen,
LBL;
unsigned int i=0,
j;
unsigned char devnum;
curLB=Char2Long(FilePointer+256);
curlen=Char2Long(FilePointer+260);
curbyte=Char2Long(FilePointer+264);
devnum=*(FilePointer+268);
LBL=Char2Long(FilePointer+269);
while (length!=0)
{
if (curlen==0)
{
return(-1);
}
if (ReadCDSector(curLB/(2048/LBL),SectorBuf,1,devnum)!=0)
{
return(-1);
}
j=(curLB%(2048/LBL))<<9;
if (curlen<(LBL-curbyte))
{
if (curlen<=length)
{
CopyBytes(SectorBuf+curbyte+j,data,curlen);
i=i+curlen;
return(i);
}
}
if (length<(LBL-curbyte))
{
CopyBytes(SectorBuf+curbyte+j,data,length);
Long2Char(curLB,FilePointer+256);
Long2Char(curlen-length,FilePointer+260);
Long2Char(curbyte+length,FilePointer+264);
return(0);
}
CopyBytes(SectorBuf+curbyte+j,data,(LBL-curbyte));
if (*(FilePointer+26)==0)
{
curLB++;
}
else
{
if ( *(FilePointer+273) == *(FilePointer+26) )
{
*(FilePointer+273)=1;
curLB=curLB + *(FilePointer+27) + 1;
}
else
{
*(FilePointer+273)=*(FilePointer+273)+1;
curLB++;
}
}
curlen=curlen-(LBL-curbyte);
length=length-(LBL-curbyte);
i=i+(LBL-curbyte);
data=data+(LBL-curbyte);
curbyte=0;
}
Long2Char(curLB,FilePointer+256);
Long2Char(curlen,FilePointer+260);
Long2Char(curbyte,FilePointer+264);
return(0);
}
void CopyBytes (unsigned char *source,unsigned char *dest,unsigned int len)
/* copy bytes from source to destination
in: *source pointer to source
*dest pointer to destination
len number of bytes
*/
{
while (len!=0)
{
*dest=*source;
len--;
dest++;
source++;
}
}
unsigned long Char2Long (unsigned char *bytes)
/* convert 4 bytes to 1 long, (LSB----MSB)
in: *char pointer to 4 bytes
out: value
*/
{
unsigned long j;
j = *(bytes+3);
j = (j<<8) + *(bytes+2);
j = (j<<8) + *(bytes+1);
j = (j<<8) + *(bytes+0);
return(j);
}
unsigned long Char2LongMSBLSB (unsigned char *bytes)
/* convert 4 bytes to 1 long, (MSB----LSB)
in: *char pointer to 4 bytes
out: value
*/
{
unsigned long j;
j = *(bytes+0);
j = (j<<8) + *(bytes+1);
j = (j<<8) + *(bytes+2);
j = (j<<8) + *(bytes+3);
return(j);
}
unsigned int Char2Int (unsigned char *bytes)
/* convert 2 bytes to 1 int, (LSB----MSB)
in: *char pointer to 2 bytes
out: value
*/
{
return( *(bytes+0) +
(*(bytes+1)<<8)
);
}
unsigned int Char2IntMSBLSB (unsigned char *bytes)
/* convert 2 bytes to 1 int, (MSB----LSB)
in: *char pointer to 2 bytes
out: value
*/
{
return( *(bytes+1) +
(*(bytes+0)<<8)
);
}
void Int2Char (unsigned int value,unsigned char *bytes)
{
*(bytes )=(value&0x00ff);
*(bytes+1)=(value&0xff00)>>8;
}
void Int2CharMSBLSB (unsigned int value,unsigned char *bytes)
{
*(bytes+1)=(value&0x00ff);
*(bytes )=(value&0xff00)>>8;
}
void Long2Char (unsigned long value,unsigned char *bytes)
{
*(bytes )=(value&0x000000ff);
*(bytes+1)=(value&0x0000ff00)>>8;
*(bytes+2)=(value&0x00ff0000)>>16;
*(bytes+3)=(value&0xff000000)>>24;
}
void Long2CharMSBLSB (unsigned long value,unsigned char *bytes)
{
*(bytes+3)=(value&0x000000ff);
*(bytes+2)=(value&0x0000ff00)>>8;
*(bytes+1)=(value&0x00ff0000)>>16;
*(bytes )=(value&0xff000000)>>24;
}
void main ()
{
unsigned int i,j,k;
unsigned char temp[512],
temp1[512],
*test;
struct structCDPosition CDPos;
struct structCDNumber CDNum;
struct structATAPIError error;
SectorCache.DeviceNumber=0xff;
printf("\nATA v0.10a");
printf("\nATAPI-CDROM v0.10a");
printf("\nATAPI audio-extension v0.00a");
printf("\nISO 9660:1988, level 2 v0.00a");
printf("\nISO 9660:Joliet-extension v0.00a");
printf("\n\nProgrammed by V.M.G. van Acht");
printf("\n(c) 1998 by VVA\n");
if (WriteIDECommand(IDEATAPIIdent,0)==0)
{
if (ReadIDEData(Device0Data,256)==0)
{
printf("Device 0: ");
PrintText(Device0Data+27,20);
printf(" - ");
PrintText(Device0Data+23,4);
printf("\n");
NumDevice=0;
}
else
{
NumDevice=0XFFFF;
}
}
else
{
NumDevice=0XFFFF;
}
if (NumDevice==0XFFFF)
{
printf("ATAPI Device 0 error\n");
return(-1);
}
if (WriteIDECommand(IDEATAPIIdent,1)==0)
{
if (ReadIDEData(Device1Data,256)==0)
{
printf("Device 1: ");
PrintText(Device1Data+27,20);
printf(" - ");
PrintText(Device1Data+23,4);
printf("\n");
NumDevice=1;
}
}
ReadTOC(Device0TOC,&Device0ISOHdr,Device0DirTable,0);
PlayAudio(40000,100000,0);
Wait(3000);
printf("\n");
for (i=0;i<0x1000;i++)
{
CDPos=ReadCDPosition(0);
PrintMSF(LBA2MSF(CDPos.Relative),0);
printf("\r");
}
PauseAudio(0,0);
Wait(1000);
PauseAudio(1,0);
Wait(10000);
StopAudio(0);
StartStopUnit(2,0);
Wait(3000);
StartStopUnit(3,0);
/* CDROM
ResetInquiry(Device0DirTable,0);
while (Inquiry(Device0DirTable,"\\",temp,0)==0)
{
PrintFileName(temp+32,Device0ISOHdr.DOSJolietRomeo);
printf("\n");
}
printf("\n");
if (ChangeDirectory(Device0DirTable,"BC5\\",0)!=0)
{
printf("\nChange Dir error");
}
ResetInquiry(Device0DirTable,0);
j=0;
while (j<7 && Inquiry(Device0DirTable,"\\",temp,0)==0)
{
PrintFileName(temp+32,Device0ISOHdr.DOSJolietRomeo);
printf("\n");
j++;
}
printf("\n");
/*
if (ChangeDirectoryUp(Device0DirTable,0)!=0)
{
printf("\nChange Dir error");
}
ResetInquiry(Device0DirTable,0);
j=0;
while (j<15 && Inquiry(Device0DirTable,"\\",temp,0)==0)
{
for (i=33;i<(33+temp[32]);i++)
{
printf("%c",temp[i]);
}
printf("\n");
j++;
}
*/
/* CR-ROM
if (OpenFile(Device0DirTable,"V*.TXT",temp,0)!=0)
{
printf("Open error");
}
else
{
while ((i=ReadFileBytes(temp,5,temp1))==0)
{
for (i=0;i<5;i++)
{
printf("%c",temp1[i]);
}
}
if (i!=-1)
{
for (j=0;i!=0;i--,j++)
{
printf("%c",temp1[j]);
}
}
}
WaitKey();
error=ATAPIError(0);
printf("\nFlag:%X",error.Flag);
printf("\nText:%s",error.Text);
*/
}
|