示例#1
0
//
// Corvus_Read_Sector
//
// Read a variably-sized chunk of data from the CHD file
//
// Pass:
//      drv:    Corvus drive id (1..15)
//      sector: Physical sector number to read from
//      buffer: Buffer to hold the data read from the disk
//      len:    Length of the buffer
//
// Returns:
//      status: Corvus status
//
UINT8 corvus_hdc_t::corvus_read_sector(UINT8 drv, UINT32 sector, UINT8 *buffer, int len) {
	hard_disk_file
			*disk;              // Structures for interface to CHD routines
	UINT8   tbuffer[512];       // Buffer to store full sector results in
	UINT16  cylinder;

	LOG(("corvus_read_sector: Read Drive: %d, physical sector: 0x%5.5x\n", drv, sector));

	disk = corvus_hdc_file(drv);
	if(!disk) {
		logerror("corvus_read_sector: Failure returned by corvus_hdc_file(%d)\n", drv);
		return STAT_FATAL_ERR | STAT_DRIVE_NOT_ONLINE;
	}

	//
	// Calculate what cylinder the sector resides on for timing purposes
	//
	cylinder = (double) sector / (double) m_sectors_per_track / (double) m_tracks_per_cylinder;
	m_delay = abs(m_last_cylinder - cylinder) * TRACK_SEEK_TIME + INTERSECTOR_DELAY;

	hard_disk_read(disk, sector, tbuffer);

	memcpy(buffer, tbuffer, len);

	m_last_cylinder = cylinder;

	LOG(("corvus_read_sector: Data read follows:\n"));
	LOG_BUFFER(tbuffer, len);

	return STAT_SUCCESS;
}
示例#2
0
UINT32 hard_disk_read(struct hard_disk_file *file, UINT32 lbasector, UINT32 numsectors, void *buffer)
{
	UINT32 hunknum = lbasector / file->hunksectors;
	UINT32 sectoroffs = lbasector % file->hunksectors;

	/* for now, just break down multisector reads into single sectors */
	if (numsectors > 1)
	{
		UINT32 total = 0;
		while (numsectors--)
		{
			if (hard_disk_read(file, lbasector++, 1, (UINT8 *)buffer + total * file->info.sectorbytes))
				total++;
			else
				break;
		}
		return total;
	}

//	printf("HDD: rd lba %x\n", lbasector);

	/* if we haven't cached this hunk, read it now */
	if (file->cachehunk != hunknum)
	{
		if (!chd_read(file->chd, hunknum, 1, file->cache))
			return 0;
		file->cachehunk = hunknum;
	}
	
	/* copy out the requested sector */
	memcpy(buffer, &file->cache[sectoroffs * file->info.sectorbytes], file->info.sectorbytes);
	return 1;
}
示例#3
0
static void read_sector_done(int which)
{
	struct ide_state *ide = &idestate[which];
	int lba = lba_address(ide), count = 0;

	/* now do the read */
	if (ide->disk)
		count = hard_disk_read(ide->disk, lba, 1, ide->buffer);

	/* by default, mark the buffer ready and the seek complete */
	if (!ide->verify_only)
		ide->status |= IDE_STATUS_BUFFER_READY;
	ide->status |= IDE_STATUS_SEEK_COMPLETE;

	/* and clear the busy and error flags */
	ide->status &= ~IDE_STATUS_ERROR;
	ide->status &= ~IDE_STATUS_BUSY;

	/* if we succeeded, advance to the next sector and set the nice bits */
	if (count == 1)
	{
		/* advance the pointers, unless this is the last sector */
		/* Gauntlet: Dark Legacy checks to make sure we stop on the last sector */
		if (ide->sector_count != 1)
			next_sector(ide);

		/* clear the error value */
		ide->error = IDE_ERROR_NONE;

		/* signal an interrupt */
		if (!ide->verify_only)
			ide->sectors_until_int--;
		if (ide->sectors_until_int == 0 || ide->sector_count == 1)
		{
			ide->sectors_until_int = ((ide->command == IDE_COMMAND_READ_MULTIPLE_BLOCK) ? ide->block_count : 1);
			signal_interrupt(ide);
		}

		/* handle DMA */
		if (ide->dma_active)
			write_buffer_to_dma(ide);

		/* if we're just verifying or if we DMA'ed the data, we can read the next sector */
		if (ide->verify_only || ide->dma_active)
			continue_read(ide);
	}

	/* if we got an error, we need to report it */
	else
	{
		/* set the error flag and the error */
		ide->status |= IDE_STATUS_ERROR;
		ide->error = IDE_ERROR_BAD_SECTOR;
		ide->bus_master_status |= IDE_BUSMASTER_STATUS_ERROR;
		ide->bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;

		/* signal an interrupt */
		signal_interrupt(ide);
	}
}
示例#4
0
// retrieve data from the SCSI controller
void am53cf96_read_data(int bytes, data8_t *pData)
{
	int i;

	scsi_regs[REG_STATUS] |= 0x10;	// indicate DMA finished

	switch (last_cmd)
	{
		case 0x03:	// REQUEST SENSE
			pData[0] = 0x80;	// valid sense
			for (i = 1; i < 12; i++)
			{
				pData[i] = 0;
			}
			break;

		case 0x28:	// READ (10 byte)
			if ((disk) && (blocks))
			{
				while (bytes > 0)
				{
					if (!hard_disk_read(disk, lba, 1, pData))
					{
						logerror("53cf96: HD read error!\n");
					}
					lba++;
					blocks--;
					bytes -= 512;
					pData += 512;
				}
			}		
			break;

	}
}
示例#5
0
/*
	imghd_read()

	Read sector(s) from MAME HD image
*/
imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, UINT32 lbasector, void *buffer)
{
	chd_interface interface_save;
	UINT32 reply;

	chd_save_interface(&interface_save);
	chd_set_interface(&imgtool_chd_interface);
	reply = hard_disk_read(disk->hard_disk, lbasector, buffer);
	chd_set_interface(&interface_save);

	return reply ? IMGTOOLERR_SUCCESS : map_chd_error(reply);
}
示例#6
0
//
// Corvus_Write_Sector
//
// Write a variably-sized chunk of data to the CHD file
//
// Pass:
//      drv:    Corvus drive id (1..15)
//      sector: Physical sector number to write to
//      buffer: Buffer to write
//      len:    Length of the buffer (amount of data to write)
//
// Returns:
//      status: Command status
//
UINT8 corvus_hdc_t::corvus_write_sector(UINT8 drv, UINT32 sector, UINT8 *buffer, int len) {
	hard_disk_file
			*disk;              // Structures for interface to CHD routines
	UINT8   tbuffer[512];       // Buffer to hold an entire sector
	UINT16  cylinder;           // Cylinder this sector resides on

	LOG(("corvus_write_sector: Write Drive: %d, physical sector: 0x%5.5x\n", drv, sector));

	disk = corvus_hdc_file(drv);
	if(!disk) {
		logerror("corvus_write_sector: Failure returned by corvus_hdc_file(%d)\n", drv);
		return STAT_FATAL_ERR | STAT_DRIVE_NOT_ONLINE;
	}

	//
	// Calculate what cylinder the sector resides on for timing purposes
	//
	cylinder = (double) sector / (double) m_sectors_per_track / (double) m_tracks_per_cylinder;
	m_delay = abs(m_last_cylinder - cylinder) * TRACK_SEEK_TIME + INTERSECTOR_DELAY;

	//
	// Corvus supports write sizes of 128, 256 and 512 bytes.  In the case of a write smaller than
	// the sector size of 512 bytes, the sector is read, the provided data is overlayed and then the
	// sector is written back out.  See pp. 5 of the Mass Storage Systems GTI for the details of this
	// wonderful functionality.
	//
	if(len == 512) {
		hard_disk_write(disk, sector, buffer);
	} else {
		hard_disk_read(disk, sector, tbuffer);      // Read the existing data into our temporary buffer
		memcpy(tbuffer, buffer, len);                   // Overlay the data with the buffer passed
		m_delay += INTERSECTOR_DELAY;                  // Add another delay because of the Read / Write
		hard_disk_write(disk, sector, tbuffer);     // Re-write the data
	}

	m_last_cylinder = cylinder;

	LOG(("corvus_write_sector: Full sector dump on a write of %d bytes follows:\n", len));
	LOG_BUFFER(len == 512 ? buffer : tbuffer, 512);

	return STAT_SUCCESS;
}
示例#7
0
文件: imghd.cpp 项目: RalfVB/mame
/*
    imghd_read()

    Read sector(s) from MAME HD image
*/
imgtoolerr_t imghd_read(struct mess_hard_disk_file *disk, UINT32 lbasector, void *buffer)
{
	UINT32 reply;
	reply = hard_disk_read(disk->hard_disk, lbasector, buffer);
	return (imgtoolerr_t)(reply ? IMGTOOLERR_SUCCESS : map_chd_error((chd_error)reply));
}