DVD Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
LoseThos
Member
Member
Posts: 112
Joined: Tue Oct 30, 2007 6:41 pm
Location: Las Vegas, NV USA
Contact:

DVD Problem

Post by LoseThos »

My CD burning code works fine but my DVD burning does not play well with Windows. If I burn a DVD, it boots my operating system and is readible from my operating system, but Windows doesn't like it. If I use a MagicISO, burning windows utility, the ISO image file works on a DVD, so the data is not the problem. When you close-out a CD or DVD, you have to send codes and I think my codes for closing a DVD are not right. Anybody know about this?

Code: Select all


void ATAPIWriteBlks(LTBlkDev *bdev,U1 *buf, U8 blk, U8 cnt)
{
    U8 U4s_avail;
    U1 *buf2;
    IDEWaitNotBusy(bdev);
    ATAPISeek(bdev,blk);

    OutP(bdev->base0+IDE_FEATURE_REG,0);
    OutP(bdev->base0+IDE_LCYL_REG,bdev->blk_size);
    OutP(bdev->base0+IDE_HCYL_REG,bdev->blk_size.u1[1]);
    OutP(bdev->base0+IDE_SELECT_REG,0xEF|bdev->unit<<4);
    OutP(bdev->base0+IDE_CMD,ATA_PACKETCMD);
    ATAPIWritePktWord(bdev,0x0400);  //FMT
    ATAPIWritePktWord(bdev,blk.u2[1]);
    ATAPIWritePktWord(bdev,blk);
    ATAPIWritePktWord(bdev,cnt.u2[1]);
    ATAPIWritePktWord(bdev,cnt);
    ATAPIWritePktWord(bdev,0x0000);
    bdev->flags|=LTBDF_LAST_WAS_WRITE;
    IDEWaitNotBusy(bdev);

    ATAPISeek(bdev,blk);

    OutP(bdev->base1+IDE_CONTROL_REG,0x8);
    OutP(bdev->base0+IDE_SELECT_REG,0xEF|bdev->unit<<4);
    OutP(bdev->base0+IDE_LCYL_REG,bdev->blk_size);
    OutP(bdev->base0+IDE_HCYL_REG,bdev->blk_size.u1[1]);
    ATACmd(bdev,ATA_PACKETCMD);
    ATAPIWritePktWord(bdev,0xAA00);  //Write
    ATAPIWritePktWord(bdev,blk.u2[1]);
    ATAPIWritePktWord(bdev,blk);
    ATAPIWritePktWord(bdev,cnt.u2[1]);
    ATAPIWritePktWord(bdev,cnt);
    ATAPIWritePktWord(bdev,0x0000);
    buf2=buf+bdev->blk_size*cnt;
    while (buf<buf2) {
	while (!(InP(bdev->base0+IDE_STATUS) & S_DRQ))
	    SwapInNextTask;
	U4s_avail=(InP(bdev->base0+IDE_HCYL_REG)<<8+InP(bdev->base0+IDE_LCYL_REG))>>2;
	if (buf+U4s_avail<<2>buf2)
	    U4s_avail=(buf2-buf)>>2;
	if (U4s_avail) {
	    RepOutSD(buf,U4s_avail,bdev->base0+IDE_DATA_REG);
	    buf+=U4s_avail<<2;
	    disk_writes+=U4s_avail>>(BLK_SIZE_BITS-2);
	}
    }
    IDEWaitNotBusy(bdev);
}

void ATAPISync(LTBlkDev *bdev)
{
    IDEWaitNotBusy(bdev);
    OutP(bdev->base1+IDE_CONTROL_REG,0x8);
    OutP(bdev->base0+IDE_SELECT_REG,0xEF|bdev->unit<<4);
    OutP(bdev->base0+IDE_LCYL_REG,bdev->blk_size);
    OutP(bdev->base0+IDE_HCYL_REG,bdev->blk_size.u1[1]);
    ATACmd(bdev,ATA_PACKETCMD);
    ATAPIWritePktWord(bdev,0x3500);  //Sync
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    IDEWaitNotBusy(bdev);
}

void ATAPIClose(LTBlkDev *bdev,I8 close_field=0x200)
{
//0x200 CD/DVD part 1
//0x300    DVD part 2
    OutP(bdev->base1+IDE_CONTROL_REG,0x8);
    OutP(bdev->base0+IDE_SELECT_REG,0xEF|bdev->unit<<4);
    OutP(bdev->base0+IDE_LCYL_REG,bdev->blk_size);
    OutP(bdev->base0+IDE_HCYL_REG,bdev->blk_size.u1[1]);
    ATACmd(bdev,ATA_PACKETCMD);
    ATAPIWritePktWord(bdev,0x5B00);  //Close
    ATAPIWritePktWord(bdev,close_field);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    ATAPIWritePktWord(bdev,0x0000);
    IDEWaitNotBusy(bdev);
}



//This is the high level code
    ATAPIWaitReady(bdev);
    while (cnt) {
	if (cnt>COPY_BUF_BLKS)
	    n=COPY_BUF_BLKS;
	else
	    n=cnt;
	if (n>bdev->max_writes)
	    n=bdev->max_writes;
	buf=d->out_buf&1 ? d->buf1:d->buf0;
	while (d->in_buf<=d->out_buf)
	    SwapInNextTask;
	ATAPIWriteBlks(bdev,buf,blk/dv,(n+dv-1)/dv);
	d->out_buf++;
	cnt-=n;
	blk+=n;
    }
    ATAPISync(bdev);
    ATAPIClose(bdev,0x200);
    if (media_type==MT_DVD)
	ATAPIClose(bdev,0x300);


Post Reply