예제 #1
0
파일: mfmhd.cpp 프로젝트: Robbbert/store1
void mfm_harddisk_device::call_unload()
{
    mfmhd_layout_params* params = m_format->get_current_params();
    mfmhd_layout_params* oldparams = m_format->get_initial_params();

    if (m_cache!=nullptr)
    {
        m_cache->cleanup();

        if (m_format->save_param(MFMHD_IL) && !params->equals_rec(oldparams))
        {
            logerror("MFM HD sector arrangement and recording specs have changed; updating CHD metadata\n");
            chd_file* chdfile = get_chd_file();

            chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 0, string_format(MFMHD_REC_METADATA_FORMAT, params->interleave, params->cylskew, params->headskew, params->write_precomp_cylinder, params->reduced_wcurr_cylinder), 0);
            if (err != CHDERR_NONE)
            {
                logerror("Failed to save MFM HD sector arrangement/recording specs to CHD\n");
            }
        }

        if (m_format->save_param(MFMHD_GAP1) && !params->equals_gap(oldparams))
        {
            logerror("MFM HD track gap specs have changed; updating CHD metadata\n");
            chd_file* chdfile = get_chd_file();

            chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 1, string_format(MFMHD_GAP_METADATA_FORMAT, params->gap1, params->gap2, params->gap3, params->sync, params->headerlen, params->ecctype), 0);
            if (err != CHDERR_NONE)
            {
                logerror("Failed to save MFM HD track gap specs to CHD\n");
            }
        }
    }
    harddisk_image_device::call_unload();
}
예제 #2
0
파일: mfmhd.c 프로젝트: JensGrabner/mame
/*
    Load the image from the CHD. We also calculate the head timing here
    because we need the number of cylinders, and for generic drives we get
    them from the CHD.
*/
bool mfm_harddisk_device::call_load()
{
	bool loaded = harddisk_image_device::call_load();

	std::string devtag(tag());
	devtag += ":format";

	m_format->set_tag(devtag);

	if (loaded==IMAGE_INIT_PASS)
	{
		std::string metadata;
		chd_file* chdfile = get_chd_file();

		if (chdfile==NULL)
		{
			logerror("%s: chdfile is null\n", tag());
			return IMAGE_INIT_FAIL;
		}

		// Read the hard disk metadata
		chd_error state = chdfile->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata);
		if (state != CHDERR_NONE)
		{
			logerror("%s: Failed to read CHD metadata\n", tag());
			return IMAGE_INIT_FAIL;
		}

		if (TRACE_CONFIG) logerror("%s: CHD metadata: %s\n", tag(), metadata.c_str());

		// Parse the metadata
		mfmhd_layout_params param;
		param.encoding = m_encoding;
		if (TRACE_CONFIG) logerror("%s: Set encoding to %d\n", tag(), m_encoding);

		if (sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &param.cylinders, &param.heads, &param.sectors_per_track, &param.sector_size) != 4)
		{
			logerror("%s: Invalid CHD metadata\n", tag());
			return IMAGE_INIT_FAIL;
		}

		if (TRACE_CONFIG) logerror("%s: CHD image has geometry cyl=%d, head=%d, sect=%d, size=%d\n", tag(), param.cylinders, param.heads, param.sectors_per_track, param.sector_size);

		if (m_max_cylinders != 0 && (param.cylinders != m_max_cylinders || param.heads != m_max_heads))
		{
			throw emu_fatalerror("Image geometry does not fit this kind of hard drive: drive=(%d,%d), image=(%d,%d)", m_max_cylinders, m_max_heads, param.cylinders, param.heads);
		}

		// MDM format specs
		param.interleave = 0;
		param.cylskew = 0;
		param.headskew = 0;
		param.write_precomp_cylinder = -1;
		param.reduced_wcurr_cylinder = -1;

		state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 0, metadata);
		if (state != CHDERR_NONE)
		{
			logerror("%s: Failed to read CHD sector arrangement/recording specs, applying defaults\n", tag());
		}
		else
		{
			sscanf(metadata.c_str(), MFMHD_REC_METADATA_FORMAT, &param.interleave, &param.cylskew, &param.headskew, &param.write_precomp_cylinder, &param.reduced_wcurr_cylinder);
		}

		if (!param.sane_rec())
		{
			if (TRACE_CONFIG) logerror("%s: Sector arrangement/recording specs have invalid values, applying defaults\n", tag());
			param.reset_rec();
		}
		else
			if (TRACE_CONFIG) logerror("%s: MFM HD rec specs: interleave=%d, cylskew=%d, headskew=%d, wpcom=%d, rwc=%d\n",
				tag(), param.interleave, param.cylskew, param.headskew, param.write_precomp_cylinder, param.reduced_wcurr_cylinder);

		state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 1, metadata);
		if (state != CHDERR_NONE)
		{
			logerror("%s: Failed to read CHD track gap specs, applying defaults\n", tag());
		}
		else
		{
			sscanf(metadata.c_str(), MFMHD_GAP_METADATA_FORMAT, &param.gap1, &param.gap2, &param.gap3, &param.sync, &param.headerlen, &param.ecctype);
		}

		if (!param.sane_gap())
		{
			if (TRACE_CONFIG) logerror("%s: MFM HD gap specs have invalid values, applying defaults\n", tag());
			param.reset_gap();
		}
		else
			if (TRACE_CONFIG) logerror("%s: MFM HD gap specs: gap1=%d, gap2=%d, gap3=%d, sync=%d, headerlen=%d, ecctype=%d\n",
				tag(), param.gap1, param.gap2, param.gap3, param.sync, param.headerlen, param.ecctype);

		m_format->set_layout_params(param);

		m_cache->init(this, m_trackimage_size, m_cachelines);

		// Head timing
		// We assume that the real times are 80% of the max times
		// The single-step time includes the settle time, so does the max time
		// From that we calculate the actual cylinder-by-cylinder time and the settle time

		m_actual_cylinders = param.cylinders;

		if (m_phys_cylinders == 0) m_phys_cylinders = m_actual_cylinders+1;
		if (m_landing_zone == 0) m_landing_zone = m_phys_cylinders-1;

		float realnext = (m_seeknext_time==0)? 10 : (m_seeknext_time * 0.8);
		float realmax = (m_maxseek_time==0)? (m_actual_cylinders * 0.2) : (m_maxseek_time * 0.8);
		float settle_us = ((m_actual_cylinders-1.0) * realnext - realmax) / (m_actual_cylinders-2.0) * 1000;
		float step_us = realnext * 1000 - settle_us;
		if (TRACE_CONFIG) logerror("%s: Calculated settle time: %0.2f ms, step: %d us\n", tag(), settle_us/1000, (int)step_us);

		m_settle_time = attotime::from_usec((int)settle_us);
		m_step_time = attotime::from_usec((int)step_us);

		m_current_cylinder = m_landing_zone;
	}
	else
	{
		logerror("%s: Could not load CHD\n", tag());
	}
	return loaded;
}