📄 temp.c
字号:
PRINT_DEBUG(printf("atapiTOC: calling atapiTOCEnt with Count=%u\n", Temp);)
Temp=atapiTOCEnt(&Contents, Temp, WhichDrive);
if(Temp)
return(Temp);
NumTracks=Contents.Hdr.LastTrk - Contents.Hdr.FirstTrk + 1;
if(NumTracks <= 0 || NumTracks > 99)
{
printf("atapiTOC: bad number of tracks %d\n", NumTracks);
return(-1);
}
if(NumTracks > MAX_TRACKS)
{
printf("Too many tracks (%u); reducing to %u.\n", NumTracks, MAX_TRACKS);
NumTracks=MAX_TRACKS;
}
Temp=sizeof(atapitocheader) + (NumTracks + 1) * sizeof(atapitocentry);
PRINT_DEBUG(printf("atapiTOC: calling atapiTOCEnt with Count=%u\n", Temp);)
Temp=atapiTOCEnt(&Contents, Temp, WhichDrive);
if(Temp)
return(Temp);
for(Temp=0; Temp <= NumTracks; Temp++)
{
Track[Temp].Min=Contents.Ent[Temp].Where.Time.Min;
Track[Temp].Sec=Contents.Ent[Temp].Where.Time.Sec;
Track[Temp].Frame=Contents.Ent[Temp].Where.Time.Frame;
printf("%02u:%02u:%02u ", Contents.Ent[Temp].Where.Time.Min, Contents.Ent[Temp].Where.Time.Sec, Contents.Ent[Temp].Where.Time.Frame);
}
printf("\n");
return(0);
}
/*****************************************************************************
name: atapiPause
action: pauses (Play == 0) or continues (Play != 0) audio CD
returns:whatever atapiCmd2() returns
*****************************************************************************/
int atapiPause(unsigned Play, unsigned WhichDrive)
{
char Pkt[12]={
ATAPI_CMD_PAUSE,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0 };
drivecmd Cmd;
PRINT_DEBUG(printf("atapiPause\n");)
Cmd.Blk=0;
Cmd.Count=0;
Cmd.Dev=WhichDrive;
Cmd.Cmd=0;
Cmd.Data=NULL;
Pkt[8]=(Play != 0);
return(atapiCmd2(&Cmd, Pkt));
}
/*
////////////////////////////////////////////////////////////////////////////
GENERAL PARTITION STUFF
////////////////////////////////////////////////////////////////////////////
*/
/*****************************************************************************
name: partProbe
action: analyzes partitions on ATA drives
*****************************************************************************/
void partProbe(void)
{
u8 Buffer[512], WhichDrive, WhichPart;
unsigned HiHead, Scale, LHeads, Heads, Sects;
long int Temp, Track;
unsigned Offset, Cyls;
drivecmd Cmd;
printf("partProbe:\n");
for(WhichDrive=0; WhichDrive < 4; WhichDrive++)
{
if(Drive[WhichDrive].IOAdr == 0) continue;
if(Drive[WhichDrive].Flags & ATA_FLG_ATAPI) continue;
/* load sector 0 (the partition table) */
Cmd.Blk=0;
Cmd.Count=512;
Cmd.Dev=WhichDrive;
Cmd.Cmd=DRV_CMD_RD;
Cmd.Data=Buffer;
Temp=ataCmd(&Cmd);
if(Temp < 0) continue;
/* see if it's valid */
if(Buffer[0x1FE] != 0x55 || Buffer[0x1FF] != 0xAA)
{
printf(" hd%1u: invalid partition table\n", WhichDrive);
continue;
}
/* check all four primary partitions for highest Heads value */
HiHead=0;
for(WhichPart=0; WhichPart < 4; WhichPart++)
{
Offset=0x1BE + 16 * WhichPart;
if(Buffer[Offset + 1] > HiHead)
HiHead=Buffer[Offset + 1];
if(Buffer[Offset + 5] > HiHead)
HiHead=Buffer[Offset + 5];
}
/* compare highest head value with heads/cylinder value from 'identify'.Check for LARGE mode and determine Scale. This test will fail unlesspartitions end on a cylinder boundary (hopefully, they do). */
HiHead++;
LHeads=Drive[WhichDrive].Heads;
if(HiHead > LHeads)
{
Scale=HiHead / LHeads;
printf(" hd%1u: LARGE mode, N=", WhichDrive);
if(Scale * LHeads == HiHead)
{
LHeads *= Scale;
printf("%u, new CHS=%u:%u:%u\n", Scale, Drive[WhichDrive].Cyls / Scale, LHeads, Drive[WhichDrive].Sects);
}
/* HiHead / Drive[WhichDrive].Heads is not an integer. */
else
printf("??? (UNKNOWN !!!)\n");
}
/* now print geometry info for all primary partitions. CHS values in eachpartition record may be faked for the benefit of MS-DOS/Win, so we ignorethem and use the 32-bit size-of-partition and sectors-preceding-partitionfields to compute CHS */
for(WhichPart=0; WhichPart < 4; WhichPart++)
{
Offset=0x1BE + 16 * WhichPart;
/* get 32-bit sectors-preceding-partition; skip if undefined partition */
Temp=*(u32 *)(Buffer + Offset + 8);
if(Temp == 0) continue;
/* convert to CHS, using LARGE mode value of Heads if necessary */
Sects=Temp % Drive[WhichDrive].Sects + 1;
Track=Temp / Drive[WhichDrive].Sects;
Heads=Track % LHeads;
Cyls=Track / LHeads;
printf(" hd%1u%c: start LBA=%8lu, start CHS=%4u:"
"%2u:%2u, ", WhichDrive, 'a' + WhichPart, Temp, Cyls, Heads, Sects);
/* get 32-bit partition size */
Temp=*(u32 *)(Buffer + Offset + 12);
printf("%lu sectors\n", Temp);
}
}
}
/*
////////////////////////////////////////////////////////////////////////////
IRQ, DEMO, AND MAIN ROUTINES
////////////////////////////////////////////////////////////////////////////
*/
#define IRQ14_VECTOR 118
#define IRQ15_VECTOR 119
#define CHAIN_INTS
//#define BUFF_SIZE 49152u
#define BUFF_SIZE 16384
drivecmd Cmd;
char Buffer[BUFF_SIZE];
#if defined(__DJGPP__)
#include <dpmi.h>
#include <go32.h>
#include <crt0.h>
_go32_dpmi_seginfo OldIRQ14Vector;
_go32_dpmi_seginfo OldIRQ15Vector;
/*****************************************************************************
name: irq14
action: IRQ 14 handler
*****************************************************************************/
void irq14(void)
{
InterruptOccured |= 0x4000;
outp(0xA0, 0x20);
nsleep(1000);
outp(0x20, 0x20);
}
/*****************************************************************************
name: irq15
action: IRQ 15 handler
*****************************************************************************/
void irq15(void)
{
InterruptOccured |= 0x8000;
outp(0xA0, 0x20);
nsleep(1000);
outp(0x20, 0x20);
}
/*****************************************************************************
name: irqStart
action: saves old interrupt vectors, installs new handlers
*****************************************************************************/
void irqStart(void)
{
_go32_dpmi_seginfo NewVector;
/* lock memory (disable paging) */
_crt0_startup_flags |= _CRT0_FLAG_LOCK_MEMORY;
_go32_dpmi_get_protected_mode_interrupt_vector(IRQ14_VECTOR, &OldIRQ14Vector);
_go32_dpmi_get_protected_mode_interrupt_vector(IRQ15_VECTOR, &OldIRQ15Vector);
NewVector.pm_selector=_my_cs();
NewVector.pm_offset=irq14;
/* ptr -> int */
_go32_dpmi_allocate_iret_wrapper(&NewVector);
#if defined(CHAIN_INTS)
_go32_dpmi_chain_protected_mode_interrupt_vector(IRQ14_VECTOR, &NewVector);
#endif
_go32_dpmi_set_protected_mode_interrupt_vector(IRQ14_VECTOR, &NewVector);
NewVector.pm_selector=_my_cs();
NewVector.pm_offset=irq15;
/* ptr -> int */
_go32_dpmi_allocate_iret_wrapper(&NewVector);
#if defined(CHAIN_INTS)
_go32_dpmi_chain_protected_mode_interrupt_vector(IRQ15_VECTOR, &NewVector);
#endif
_go32_dpmi_set_protected_mode_interrupt_vector(IRQ15_VECTOR, &NewVector);
}
/*****************************************************************************
name: irqEnd
action: restores old IRQ handlers
*****************************************************************************/
void irqEnd(void)
{
_go32_dpmi_set_protected_mode_interrupt_vector(IRQ14_VECTOR, &OldIRQ14Vector);
_go32_dpmi_set_protected_mode_interrupt_vector(IRQ15_VECTOR, &OldIRQ15Vector);
}
#elif defined(__BORLANDC__)
void interrupt (*OldIRQ14Vector)(void);
void interrupt (*OldIRQ15Vector)(void);
/*****************************************************************************
name: irq14
action: IRQ 14 handler
*****************************************************************************/
void interrupt irq14(void)
{
InterruptOccured |= 0x4000;
#if defined(CHAIN_INTS)
_chain_intr(OldIRQ14Vector);
#else
outp(0xA0, 0x20);
nsleep(1000);
outp(0x20, 0x20);
#endif
}
/*****************************************************************************
name: irq15
action: IRQ 15 handler
*****************************************************************************/
void interrupt irq15(void)
{
InterruptOccured |= 0x8000;
#if defined(CHAIN_INTS)
_chain_intr(OldIRQ15Vector);
#else
outp(0xA0, 0x20);
nsleep(1000);
outp(0x20, 0x20);
#endif
}
/*****************************************************************************
name: ctrlBrk
action: Ctrl-Brk handler
Does not return, but calls exit() instead.
*****************************************************************************/
int ctrlBrk(void)
{
printf("*** CtrlBrk pressed ***\n");
setvect(IRQ14_VECTOR, OldIRQ14Vector);
setvect(IRQ15_VECTOR, OldIRQ15Vector);
return(0);
}
/*****************************************************************************
name: irqStart
action: saves old interrupt vectors, installs new handlers
*****************************************************************************/
void irqStart(void)
{
ctrlbrk(ctrlBrk);
OldIRQ14Vector=getvect(IRQ14_VECTOR);
OldIRQ15Vector=getvect(IRQ15_VECTOR);
setvect(IRQ14_VECTOR, irq14);
setvect(IRQ15_VECTOR, irq15);
}
/*****************************************************************************
name: irqEnd
action: restores old IRQ handlers
*****************************************************************************/
void irqEnd(void)
{
setvect(IRQ14_VECTOR, OldIRQ14Vector);
setvect(IRQ15_VECTOR, OldIRQ15Vector);
}
#else
#error Not DJGPP, not Borland C. Sorry.
#endif
/*****************************************************************************
name: demo
action: loads interesting sectors from ATA and ATAPI drives
and dumps them in hex
*****************************************************************************/
void demo(void)
{
unsigned Count, WhichDrive;
for(WhichDrive=0; WhichDrive < 4; WhichDrive++)
{
if(Drive[WhichDrive].IOAdr == 0) continue;
Cmd.Dev=WhichDrive;
Cmd.Cmd=DRV_CMD_RD;
Cmd.Data=Buffer;
if(Drive[WhichDrive].Flags & ATA_FLG_ATAPI)
/* CD-ROM has it's root directory at logical block #16. According toISO-9660, the first 16 blocks (2048 bytes each) are all zeroes. (Theseblocks might now be used for El Torrito boot-from-CD.) */
{
Count=17;
Cmd.Blk=17 - Count;
Cmd.Count=Count << ATAPI_LG_SECTSIZE;
printf("atapiCmd() returned %d\n", atapiCmd(&Cmd));
dump(Buffer + ATAPI_SECTSIZE * (Count - 1), 96);
}
else
/* load first sector of first partition, plus the MultSect sectors before it,to demonstrate multisector read (if supported) */
{
Count=Drive[WhichDrive].MultSect + 1;
Cmd.Blk=Drive[WhichDrive].Sects + 1 - Count;
Cmd.Count=Count << ATA_LG_SECTSIZE;
printf("ataCmd() returned %d\n", ataCmd(&Cmd));
dump(Buffer + ATA_SECTSIZE * (Count - 1), 96);
}
}
}
/*****************************************************************************
name: main
*****************************************************************************/
int main(void)
{
unsigned char Data, WhichDrive, Temp;
long Blk, Count;
irqStart();
/* enable IRQ14 and IRQ15 at the 2nd 8259 PIC chip */
outp(0xA1, inp(0xA1) & ~0xC0);
ataProbe();
partProbe();
#ifdef DEMO
/* atapiCmd demonstrates data CDs */
demo();
#else
/* atapiTOC and atapiPlay demonstrate audio CDs */
for(WhichDrive=0; WhichDrive < 4; WhichDrive++)
{
if(Drive[WhichDrive].IOAdr && (Drive[WhichDrive].Flags & ATA_FLG_ATAPI))
break;
}
if(WhichDrive == 4)
{
printf("No ATAPI devices detected.\n");
goto BAIL;
}
printf("\n");
atapiTOC(WhichDrive);
for(Count=3; Count; Count--)
/* play from 13:11:32 to 18:01:00 -- Zeppelin */
{
Temp=atapiPlay(WhichDrive, (13ul * 60 + 11) * 75 + 32, (18ul * 60 + 1) * 75 + 0);
if(Temp)
printf("atapiPlay returned error %d, "
"retrying...\n", Temp);
else
break;
}
#endif
#ifdef ERASE
#define START_BLK 2048ul
#define NUM_BLKS 8192ul
printf( "\n"
"********************************************************\n"
"*** DANGER! ***\n"
"********************************************************\n"
"THIS OPERATION WILL ERASE PORTIONS OF YOUR HARD DRIVE!!!\n"
"\n"
"Press 'y' to continue.\n"
"\x07\x07\x07");
Temp=getch();
if(Temp != 'y' && Temp !='Y') goto BAIL;
printf( "\n"
"********************************************************\n"
"*** SECOND WARNING! ***\n"
"********************************************************\n"
"Are you sure you want to ERASE YOUR HARD DRIVE?\n"
"\n" "Press 'p' to proceed.\n"
"\x07");
Temp=getch();
if(Temp != 'p' && Temp != 'P') goto BAIL;
Cmd.Dev=0;
srand(2);
Cmd.Cmd=DRV_CMD_WR;
/* write NUM_BLKS of pseudorandom data to beginning of drive. SkipsSTART_BLK sectors, which may or may not leave the FAT, DOS kernel files,and COMMAND.COM intact. THIS ERASES DATA ON THE DRIVE!!! */
for(Blk=START_BLK; Blk < START_BLK + NUM_BLKS; )
{
for(Temp=0; Temp < BUFF_SIZE; Temp++)
Buffer[Temp]=rand();
printf("writing Blk %lu\r", Blk);
Cmd.Data=Buffer;
Cmd.Blk=Blk;
Count=min(BUFF_SIZE >> 9, START_BLK + NUM_BLKS - Blk);
Cmd.Count=Count << 9;
Temp=ataCmd(&Cmd);
if(Temp)
{
printf("\n"
"ataCmd(write) returned %d\n", Temp);
break;
}
Blk += Count;
}
printf("\n");
srand(2);
Cmd.Cmd=DRV_CMD_RD;
/* read NUM_BLKS of data from beginning of drive, verify against samepseudorandom sequence that was written */
for(Blk=START_BLK; Blk < START_BLK + NUM_BLKS; )
{
printf("reading Blk %lu\r", Blk);
Cmd.Data=Buffer;
Cmd.Blk=Blk;
Count=min(BUFF_SIZE >> 9, START_BLK + NUM_BLKS - Blk);
Cmd.Count=Count << 9;
Temp=ataCmd(&Cmd);
if(Temp)
{
printf("\n"
"ataCmd(read) returned %d\n", Temp);
break;
}
for(Temp=0; Temp < min(BUFF_SIZE, (START_BLK + NUM_BLKS - Blk) << 9); Temp++)
{
Data=rand();
if(Buffer[Temp] != Data)
{
printf("\n"
"verify failed, Blk %lu, offset "
"%u (wanted %u, got %u)\n", Blk, Temp, Data, Buffer[Temp]);
break;
}
}
Blk += Count;
}
#endif
BAIL:
printf("\n");
irqEnd();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -