summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/wd2010.h
blob: 5cba995b3da11e04de4a4f60f2754c3b5323ee6f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Western Digital WD2010 Winchester Disk Controller

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

#ifndef MAME_MACHINE_WD2010_H
#define MAME_MACHINE_WD2010_H

#pragma once




//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_WD2010_OUT_INTRQ_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_intrq_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_BDRQ_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_bdrq_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_BCR_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_bcr_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_BRDY_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_brdy_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_BCS_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_bcs_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_BCS_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_bcs_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_DIRIN_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_dirin_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_STEP_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_step_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_RWC_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_rwc_callback(DEVCB_##_devcb);

#define MCFG_WD2010_OUT_WG_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_out_wg_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_DRDY_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_drdy_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_INDEX_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_index_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_WF_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_wf_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_TK000_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_tk000_callback(DEVCB_##_devcb);

#define MCFG_WD2010_IN_SC_CB(_devcb) \
	downcast<wd2010_device &>(*device).set_in_sc_callback(DEVCB_##_devcb);

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

// ======================> wd2010_device

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

	template <class Object> devcb_base &set_out_intrq_callback(Object &&cb) { return m_out_intrq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_bdrq_callback(Object &&cb) { return m_out_bdrq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_bcr_callback(Object &&cb) { return m_out_bcr_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_brdy_callback(Object &&cb) { return m_in_brdy_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_bcs_callback(Object &&cb) { return m_in_bcs_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_bcs_callback(Object &&cb) { return m_out_bcs_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_dirin_callback(Object &&cb) { return m_out_dirin_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_step_callback(Object &&cb) { return m_out_step_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_rwc_callback(Object &&cb) { return m_out_rwc_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_out_wg_callback(Object &&cb) { return m_out_wg_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_drdy_callback(Object &&cb) { return m_in_drdy_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_index_callback(Object &&cb) { return m_in_index_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_wf_callback(Object &&cb) { return m_in_wf_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_tk000_callback(Object &&cb) { return m_in_tk000_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_in_sc_callback(Object &&cb) { return m_in_sc_cb.set_callback(std::forward<Object>(cb)); }
	auto out_intrq_callback() { return m_out_intrq_cb.bind(); }
	auto out_bdrq_callback() { return m_out_bdrq_cb.bind(); }
	auto out_bcr_callback() { return m_out_bcr_cb.bind(); }
	auto in_brdy_callback() { return m_in_brdy_cb.bind(); }
	auto in_bcs_callback() { return m_in_bcs_cb.bind(); }
	auto out_bcs_callback() { return m_out_bcs_cb.bind(); }
	auto out_dirin_callback() { return m_out_dirin_cb.bind(); }
	auto out_step_callback() { return m_out_step_cb.bind(); }
	auto out_rwc_callback() { return m_out_rwc_cb.bind(); }
	auto out_wg_callback() { return m_out_wg_cb.bind(); }
	auto in_drdy_callback() { return m_in_drdy_cb.bind(); }
	auto in_index_callback() { return m_in_index_cb.bind(); }
	auto in_wf_callback() { return m_in_wf_cb.bind(); }
	auto in_tk000_callback() { return m_in_tk000_cb.bind(); }
	auto in_sc_callback() { return m_in_sc_cb.bind(); }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );

	void buffer_ready(bool state);

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

	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

private:
	void compute_correction(uint8_t data);
	void set_parameter(uint8_t data);
	void restore(uint8_t data);
	void seek(uint8_t data);
	void read_sector(uint8_t data);
	void write_sector(uint8_t data);
	void scan_id(uint8_t data);
	void update_sdh(uint8_t new_sector_size, uint8_t new_head, uint16_t new_cylinder, uint8_t new_sectornr);
	void auto_scan_id(uint8_t data);
	void format(uint8_t data);

	devcb_write_line    m_out_intrq_cb;
	devcb_write_line    m_out_bdrq_cb;
	devcb_write_line    m_out_bcr_cb;
	devcb_read8         m_in_bcs_cb;
	devcb_read_line     m_in_brdy_cb;
	devcb_write8        m_out_bcs_cb;
	devcb_write_line    m_out_dirin_cb;
	devcb_write_line    m_out_step_cb;
	devcb_write_line    m_out_rwc_cb;
	devcb_write_line    m_out_wg_cb;
	devcb_read_line     m_in_drdy_cb;
	devcb_read_line     m_in_index_cb;
	devcb_read_line     m_in_wf_cb;
	devcb_read_line     m_in_tk000_cb;
	devcb_read_line     m_in_sc_cb;

	uint8_t m_status;
	uint8_t m_error;
	uint8_t m_task_file[8];

	emu_timer   *cmd_timer;
	emu_timer   *complete_write_when_buffer_ready_high;
	emu_timer   *deassert_write_when_buffer_ready_low;
	emu_timer   *deassert_read_when_buffer_ready_high;

	void complete_write_sector(uint8_t status);
	void complete_cmd(uint8_t status);
	void complete_immediate(uint8_t status);

	bool is_buffer_ready;

	uint32_t m_present_cylinder; // Present Cylinder Position Register
};

// device type definition
DECLARE_DEVICE_TYPE(WD2010, wd2010_device)

#endif // MAME_MACHINE_WD2010_H