summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/wd1010.h
blob: 70d8a68716314b334812536a411935917fac09d7 (plain) (tree)
1
                       



























                                                                                                       

                                                                 
                                                               

                                                                   


                                                                 

                                                
 

                               
                             
 



                                                           



                                                                                                      



                                             



                                             



































                                                               

                                  
                                 





                                     
                                     













                                                         

                                       
                                      

                                        











                                             

                                 

                    
                     











                                
                       





                                          
// license:BSD-3-Clause
// copyright-holders:Dirk Best
/***************************************************************************

    Western Digital WD1010-05 Winchester Disk Controller

***************************************************************************/

#ifndef MAME_MACHINE_WD1010_H
#define MAME_MACHINE_WD1010_H

#pragma once

#include "imagedev/harddriv.h"


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> wd1010_device

class wd1010_device : public device_t
{
public:
	// construction/destruction
	wd1010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	auto out_intrq_callback() { return m_out_intrq_cb.bind(); }
	auto out_bdrq_callback() { return m_out_bdrq_cb.bind(); }
	auto out_bcs_callback() { return m_out_bcs_cb.bind(); }
	auto out_bcr_callback() { return m_out_bcr_cb.bind(); }
	auto out_dirin_callback() { return m_out_dirin_cb.bind(); }
	auto out_wg_callback() { return m_out_wg_cb.bind(); }
	auto in_data_callback() { return m_in_data_cb.bind(); }
	auto out_data_callback() { return m_out_data_cb.bind(); }

	uint8_t read(offs_t offset);
	void write(offs_t offset, uint8_t data);

	void drdy_w(int state);
	void brdy_w(int state);
	void sc_w(int state);

	// actually inputs to the controller from the drive
	int sc_r();
	int tk000_r();

	// HACK: head selection is not actually controlled by the wd1010, but this emulation currently
	// works as if it does; this function allows heads beyond the 3-bit range of the sdh register.
	void head_w(uint8_t head) { m_head = head; }

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	TIMER_CALLBACK_MEMBER(update_seek);
	TIMER_CALLBACK_MEMBER(delayed_read);
	TIMER_CALLBACK_MEMBER(delayed_write);

private:
	enum
	{
		STATUS_ERR = 0x01, // error
		STATUS_CIP = 0x02, // command in progress
		STATUS_RSV = 0x04, // reserved
		STATUS_DRQ = 0x08, // data request
		STATUS_SC  = 0x10, // seek complete
		STATUS_WF  = 0x20, // write fault
		STATUS_RDY = 0x40, // drive ready
		STATUS_BSY = 0x80  // controller busy
	};

	enum
	{
		ERR_DM   = 0x01, // data address mark not found
		ERR_TK   = 0x02, // track zero error
		ERR_AC   = 0x04, // aborted command
		ERR_RSV1 = 0x08, // reserved, forced to 0
		ERR_ID   = 0x10, // id not found
		ERR_RSV2 = 0x20, // reserved, forced to 0
		ERR_CRC  = 0x40, // crc error
		ERR_BB   = 0x80  // bad block
	};

	enum
	{
		CMD_RESTORE = 1,
		CMD_READ_SECTOR = 2,
		CMD_WRITE_SECTOR = 3,
		CMD_SCAN_ID = 4,
		CMD_WRITE_FORMAT = 5,
		CMD_SEEK = 7
	};

	void set_error(int error);
	void set_intrq(int state);
	void set_bdrq(int state);
	attotime get_stepping_rate();
	void start_command();
	void end_command();
	int get_lbasector();

	// extract values from sdh
	int head() { return m_head; }
	int drive() { return (m_sdh >> 3) & 0x03; }
	int sector_size()
	{
		const int S[4] = { 256, 512, 1024, 128 };
		return S[(m_sdh >> 5) & 0x03];
	}

	void cmd_restore();
	void cmd_read_sector();
	void cmd_write_sector();
	void cmd_scan_id();
	void cmd_seek();

	devcb_write_line m_out_intrq_cb;
	devcb_write_line m_out_bdrq_cb;
	devcb_write_line m_out_bcs_cb;
	devcb_write_line m_out_bcr_cb;
	devcb_write_line m_out_dirin_cb;
	devcb_write_line m_out_wg_cb;
	devcb_read8 m_in_data_cb;
	devcb_write8 m_out_data_cb;

	struct
	{
		harddisk_image_device *drive;
		uint8_t head;
		uint16_t cylinder;
		uint8_t sector;
	} m_drives[4];

	emu_timer *m_seek_timer;
	emu_timer *m_read_timer;
	emu_timer *m_write_timer;

	int m_intrq;
	//int m_bdrq;
	int m_brdy;
	uint8_t m_stepping_rate;
	uint8_t  m_command;

	// task file registers
	uint8_t m_error;
	uint8_t m_precomp;
	uint8_t m_sector_count;
	uint8_t m_sector_number;
	uint16_t m_cylinder;
	uint8_t m_sdh;
	uint8_t m_status;
	uint8_t m_head;
};

// device type definition
DECLARE_DEVICE_TYPE(WD1010, wd1010_device)

#endif // MAME_MACHINE_WD1010_H