⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata_cmds.c

📁 电子盘DEMO板程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}

	/* If any partition in the requested range is protected (or OTP) - FAIL*/
	for(i=firstPartToRemove; (i<=lastPartToRemove) && (simDev->partitions[i].wActive); i++)
	{
		if( (!simDev->partitions[i].wAuthenticated) ||
			((simDev->partitions[i].info.dwCommandFlagsOrStatuses & DOCH_CFSB_PERM_LOCKED) == DOCH_CFSB_PERM_LOCKED) )
			
		{
			simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
			return -1;
		}
	}

#ifndef DOCH_MEMMAP_FILE
	for(i=firstPartToRemove; (i<=lastPartToRemove) && (simDev->partitions[i].wActive); i++)
	{
		tffsset( (simDev->bStorage + simDev->partitions[i].dwOffset), 0, (simDev->partitions[i].dwSize<<DOCH_SECTOR_SIZE_BITS));
		tffsset(&simDev->partitions[i], 0, sizeof(simDev->partitions[i]));
		diskOnChipDeviceInfo->wTotalNumOfPartitions--;
	}

#else /*DOCH_MEMMAP_FILE*/

	for(i=firstPartToRemove; (i<=lastPartToRemove) && (simDev->partitions[i].wActive); i++)
	{
		tffsset(&simDev->partitions[i], 0, sizeof(simDev->partitions[i]));
		diskOnChipDeviceInfo->wTotalNumOfPartitions--;
	}

	if(simFileIO(simSocket, SIM_ITEM_PARTITIONS, simSocket->selDevNum, FALSE, (void*)&(simDev->partitions)))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

#endif /*DOCH_MEMMAP_FILE*/


	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |=  DOCH_READY;
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;

	return 0;
}

static FLSNative simAddPartition(DOCH_SimDevice* simDev)
{
	DOCH_SimSocket* simSocket = getSimSocket();

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	simSocket->cmdBuffer.sbBuffer = getPartSetupInfo();
	simSocket->cmdBuffer.nBufferLen = sizeof(DOCH_PartitionFormatInfo);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;

	return 0;
}

static FLSNative simSetPartitionProperties(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;

	DOCH_SimSocket* simSocket = getSimSocket();
	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 (CHECK_PARTITION | CHECK_WRITE_ACCESS),
					 simSocket->in_regs.bSectorCount,
					 0,
					 0,
					 0);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

	simSocket->cmdBuffer.sbBuffer = getSandBox();
	simSocket->cmdBuffer.nBufferLen = sizeof(DOCH_PartitionFormatInfo);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_WRITE;

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return rc;
}

static FLSNative simSetPartitionUserAttr(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;

	DOCH_SimSocket* simSocket = getSimSocket();
	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 (CHECK_PARTITION | CHECK_WRITE_ACCESS),
					 simSocket->in_regs.bSectorCount,
					 0,
					 0,
					 0);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

	simSocket->cmdBuffer.sbBuffer = getSandBox();
	simSocket->cmdBuffer.nBufferLen = sizeof(DOCH_PartitionUserAttr);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_WRITE;

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return rc;
}

static FLSNative simGetPartitionUserAttr(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;
	DOCH_SimSocket* simSocket = getSimSocket();
	FLSNative  partNum = simSocket->in_regs.bSectorCount;
	FLByte i = 0;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 CHECK_PARTITION /*| CHECK_AUTHENTICATION*/,
					 partNum,
					 0,
					 0,
					 0);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

#ifdef DOCH_MEMMAP_FILE

	if(simFileIO(simSocket, SIM_ITEM_PARTITIONS, simSocket->selDevNum, TRUE, (void*)&(simDev->partitions)))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

#endif /*DOCH_MEMMAP_FILE*/

	simSocket->cmdBuffer.sbBuffer = getSandBox();
	tffscpy(simSocket->cmdBuffer.sbBuffer, 
			&simDev->partitions[partNum].userAttr,
			sizeof(simDev->partitions[partNum].userAttr));

	simSocket->cmdBuffer.nBufferLen = sizeof(DOCH_PartitionUserAttr);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	/*Fill info as needed*/
	simDev->partitions[partNum].info.nPartitionSize = simDev->partitions[partNum].dwRequestedSize;
	simDev->partitions[partNum].info.wRecommendedSectorsPerCluster = 8;
	simDev->partitions[partNum].info.wNormalAreaSectorsInErasableUnit = 512;

	/*Fill info as needed*/
	i = 0;
	while(simDev->partitions[i].wActive)
	{
		simDev->partitions[i].wAuthenticated = simDev->bPpartitionAuthenticated[i];
		if (simDev->partitions[i].wAuthenticated)
		{
			simDev->partitions[i].info.dwCommandFlagsOrStatuses|= DOCH_CFSB_USER_AUTHENTICATED;
		}else
		{
			simDev->partitions[i].info.dwCommandFlagsOrStatuses&= ~DOCH_CFSB_USER_AUTHENTICATED;
		}
		i++;
	}

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return rc;
}

static FLSNative simIdentifyDevice(DOCH_SimDevice* simDev)
{
	DOCH_SimSocket* simSocket = getSimSocket();

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	simSocket->cmdBuffer.sbBuffer = (FLByte *)&simDev->driveParameters;
	simSocket->cmdBuffer.nBufferLen = DOCH_SECTOR_SIZE;/*Hardcoded - length of identify must be 1 sector*/
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	simFillIdentifyDeviceData(simDev);

	/* Now that data is ready, set DRQ and clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return 0;
}

static FLSNative simDLMcode(DOCH_SimDevice* simDev)
{
	DOCH_SimSocket* simSocket = getSimSocket();

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	simSocket->cmdBuffer.sbBuffer = simDev->bEtffsCode[0];
	simSocket->cmdBuffer.nBufferLen = (simSocket->in_regs.bSectorCount + (simSocket->in_regs.bLBALow<<8))
											* DOCH_SECTOR_SIZE;
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);

	if(simSocket->in_regs.bErrorFeature == 0x7)
	{
		simSocket->cmdBuffer.nDirection = SIM_WRITE;
		simDev->dwEtffsSize = (simSocket->cmdBuffer.nBufferLen >>DOCH_SECTOR_SIZE_BITS);
	}

	else if(simSocket->in_regs.bErrorFeature == 0xFF)
		simSocket->cmdBuffer.nDirection = SIM_READ;
	else
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

	/* Now that data is ready, set DRQ and clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return 0;
}

static FLSNative simPartitionInfo(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;
	DOCH_SimSocket* simSocket = getSimSocket();
	FLSNative  partNum = simSocket->in_regs.bSectorCount;
	FLByte i = 0;
	FLDword winSize8KB;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 CHECK_PARTITION /*| CHECK_AUTHENTICATION*/,
					 partNum,
					 0,
					 0,
					 0);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

#ifdef DOCH_MEMMAP_FILE

	if(simFileIO(simSocket, SIM_ITEM_PARTITIONS, simSocket->selDevNum, TRUE, (void*)&(simDev->partitions)))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

#endif /*DOCH_MEMMAP_FILE*/

	simSocket->cmdBuffer.sbBuffer = (FLByte *)&simDev->partitions[partNum].info;
	simSocket->cmdBuffer.nBufferLen = sizeof(DOCH_PartitionInfo);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	/*Fill info as needed*/
	simDev->partitions[partNum].info.nPartitionSize = simDev->partitions[partNum].dwRequestedSize;
	simDev->partitions[partNum].info.wRecommendedSectorsPerCluster = 8;
	simDev->partitions[partNum].info.wNormalAreaSectorsInErasableUnit = 512;
	
	while(simDev->partitions[i].wActive)
	{
		simDev->partitions[i].wAuthenticated = simDev->bPpartitionAuthenticated[i];
		if (simDev->partitions[i].wAuthenticated)
		{
			simDev->partitions[i].info.dwCommandFlagsOrStatuses|= DOCH_CFSB_USER_AUTHENTICATED;
		}else
		{
			simDev->partitions[i].info.dwCommandFlagsOrStatuses&= ~DOCH_CFSB_USER_AUTHENTICATED;
		}
		i++;
	}

	if(partNum==DOCH_IPL_PARTITION) /* IPL partition special settings */
	{
		simDev->partitions[partNum].info.nPartitionSize = simDev->dwXIPMaxSize;
		winSize8KB = (simDev->wIPLMode & DOCH_IPL_MODE_8KB_WINDOW);
		
		switch( simDev->wIPLMode & 0x000F )
		{
		case DOCH_IPL_MODE_NORMAL_RAM:
			if(winSize8KB == DOCH_IPL_MODE_8KB_WINDOW)
				simDev->partitions[partNum].info.nFastAreaSize = 4;
			else
				simDev->partitions[partNum].info.nFastAreaSize = 64;
			break;
		case DOCH_IPL_MODE_VIRTUAL_RAM:
			if(winSize8KB == DOCH_IPL_MODE_8KB_WINDOW)
				simDev->partitions[partNum].info.nFastAreaSize = 16;
			else
				simDev->partitions[partNum].info.nFastAreaSize = 256;
			break;
		case DOCH_IPL_MODE_PAGED_RAM:
			simDev->partitions[partNum].info.nFastAreaSize = 512;
			break;
		}

		if(simDev->partitions[partNum].dwRequestedSize < simDev->partitions[partNum].info.nFastAreaSize)
			simDev->partitions[partNum].info.nFastAreaSize = simDev->partitions[partNum].dwRequestedSize;
	}/* update IPL parameters */

	/* Now that data is ready, set DRQ and clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;

	return rc;
}

static FLSNative simSetDefaultPartition(DOCH_SimDevice* simDev)
{
	/*TBD*/
	return 0;
}

static FLSNative simIdentifyDiskOnChipDevice(DOCH_SimDevice* simDev)
{
	DOCH_SimSocket* simSocket = getSimSocket();
	DOCH_DeviceInfo* diskOnChipDeviceInfo = (DOCH_DeviceInfo*)getDiskOnChipDeviceInfo(simSocket->selDevNum);
	FLSNative  rc = 0;
	register int i;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

#ifdef DOCH_MEMMAP_FILE

	if(simFileIO(simSocket, SIM_ITEM_DEV_INFO, simSocket->selDevNum, TRUE, (void*)(diskOnChipDeviceInfo)))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -