If I have this in bochs config:
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=cdrom, path="Win98SE.iso", status=inserted
ata0-slave: type=disk, path="hd.img", cylinders=128, heads=10, spt=63
My code detects first the ATAPI CD drive, then the 40mb HD image... howerver... if I change the master/slave around like so:
ata0-master: type=disk, path="hd.img", cylinders=128, heads=10, spt=63
ata0-slave: type=cdrom, path="Win98SE.iso", status=inserted
It finds the 40mb HD, but fails to see the cd-rom drive. If I set up ata1 with another Hd image, it misses it completely, unless I have no devices on ata0, then it finds it no problems. It seems like an issue with bochs, but so many people use it without issues.
Another similar, but seperate issue, if I send the ATA Identify command (or ATAPI for cd roms), wait for the DRQ bit to be set, and rep insw, it fails, with bochs complaining the DRQ bit isn't set (which it is, because I check it before proceeding). However, if I instead change my rep insw with a loop of input words, it works perfectly and all the data matches correctly. Any idea why it won't let me rep insw (even though that's what the spec recommends), but it'll let me inport all the data no issues? Both are 16-bit (like specified) operands, so i have no clue, i'm only reading 512 bytes (256 words, but it complains even if I set it to read a single word using rep insw). Some code posted below for the major parts.
Code: Select all
[global Rep_In16]
Rep_In16:
push ebp
mov ebp, esp
add ebp, 8
pusha
mov edi, [ebp]
mov edx, [ebp+4]
mov ecx, [ebp+8]
cld ;clear direction bit
rep insw
popa
pop ebp
ret
Code: Select all
void IdentifyDevice(struct DriveInfo_S *di)
{
struct ATA2_S *ptrATAInfo;
u16 *ptrBuffer;
u32 Ctr;
u8 Temp;
//Select correct drive
Outport8(di->IOAddr + ATA_REG_DRVHD, di->DrvSel);
InactiveWait(1); //Delay 1ms for drive selection
MyPrintf("Issuing ATA Identify...\n");
//Issue our 'Identify ATA' command
Outport8(di->IOAddr + ATA_REG_CMD, ATA_CMD_ID);
Temp = WaitStat(di->IOAddr,ATA_STAT_RDY | ATA_STAT_DRQ ,WAIT_ID); //Ready or DRQ
if (Temp & 1) //Error?
{ //Could still be a CD-rom drive...
MyPrintf("Not ATA, Issuing ATAPI Identify...\n");
Outport8(di->IOAddr + ATA_REG_CMD, ATA_CMD_PID); //ATAPI Identify
Temp = WaitStat(di->IOAddr,ATA_STAT_RDY | ATA_STAT_DRQ,WAIT_PID);
if (Temp & 1) //Error?
{ //Nope not a CD-rom either!
return;
}
//Ok, we got a CD-Rom drive...
MyPrintf("Found CD-Rom Drive: 0x%x %d\n",di->IOAddr,(di->DrvSel/0x10)-0xA);
di->DriveType = ataCDRom;
}
else
{
di->DriveType = ataHardDisk;
MyPrintf("Found hard-disk: 0x%x 0x%d\n",di->IOAddr,(di->DrvSel/0x10)-0xA); //0xA0, 0xB0..
}
//ATA Ready already set, so lets use it :)
if (Temp & ATA_STAT_DRQ) //Was DRQ set?
{
//Yay, we can read it now :)
ptrATAInfo = pMalloc(1); //Grab a page, 4k is plenty ;)
ptrBuffer = (u16*)ptrATAInfo;
for (Ctr=0;Ctr!=256;++Ctr) //256 inputs
ptrBuffer[Ctr] = Inport16(di->IOAddr + ATA_REG_DATA); //Input word
// Rep_In16(ptrATAInfo,di->IOAddr + ATA_REG_DATA, 256); //Read 256 words in, or 512 bytes.
di->SizeLBA = ptrATAInfo->LBASects;
MyPrintf(" Drive Size: %dkb\n",di->SizeLBA/2);
pFree(ptrATAInfo,1); //Release the page when done
}
else
{
MyPrintf("DRQ never changed for me :(\n");
}
}