summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/victor9k_fdc.h
blob: 21c88ebfabf0d96505cf31b2bcac5fc5942fccfc (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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Victor 9000 floppy disk controller emulation

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

#pragma once

#ifndef __VICTOR_9000_FDC__
#define __VICTOR_9000_FDC__

#include "emu.h"
#include "cpu/mcs48/mcs48.h"
#include "formats/victor9k_dsk.h"
#include "imagedev/floppy.h"
#include "machine/6522via.h"
#include "machine/fdc_pll.h"



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

#define MCFG_VICTOR_9000_FDC_IRQ_CB(_write) \
	devcb = &victor_9000_fdc_t::set_irq_wr_callback(*device, DEVCB_##_write);

#define MCFG_VICTOR_9000_FDC_SYN_CB(_write) \
	devcb = &victor_9000_fdc_t::set_syn_wr_callback(*device, DEVCB_##_write);

#define MCFG_VICTOR_9000_FDC_LBRDY_CB(_write) \
	devcb = &victor_9000_fdc_t::set_lbrdy_wr_callback(*device, DEVCB_##_write);



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

// ======================> victor_9000_fdc_t

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

	template<class _Object> static devcb_base &set_irq_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_irq_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_syn_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_syn_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_lbrdy_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_lbrdy_cb.set_callback(object); }

	DECLARE_READ8_MEMBER( cs5_r ) { return m_via4->read(space, offset); }
	DECLARE_WRITE8_MEMBER( cs5_w ) { m_via4->write(space, offset, data); }
	DECLARE_READ8_MEMBER( cs6_r ) { return m_via6->read(space, offset); }
	DECLARE_WRITE8_MEMBER( cs6_w ) { m_via6->write(space, offset, data); }
	DECLARE_READ8_MEMBER( cs7_r );
	DECLARE_WRITE8_MEMBER( cs7_w );

	DECLARE_FLOPPY_FORMATS( floppy_formats );

	DECLARE_READ8_MEMBER( floppy_p1_r );
	DECLARE_WRITE8_MEMBER( floppy_p1_w );
	DECLARE_READ8_MEMBER( floppy_p2_r );
	DECLARE_WRITE8_MEMBER( floppy_p2_w );
	DECLARE_READ8_MEMBER( tach0_r );
	DECLARE_READ8_MEMBER( tach1_r );
	DECLARE_WRITE8_MEMBER( da_w );

	DECLARE_READ8_MEMBER( via4_pa_r );
	DECLARE_WRITE8_MEMBER( via4_pa_w );
	DECLARE_READ8_MEMBER( via4_pb_r );
	DECLARE_WRITE8_MEMBER( via4_pb_w );
	DECLARE_WRITE_LINE_MEMBER( wrsync_w );
	DECLARE_WRITE_LINE_MEMBER( via4_irq_w );

	DECLARE_READ8_MEMBER( via5_pa_r );
	DECLARE_WRITE8_MEMBER( via5_pb_w );
	DECLARE_WRITE_LINE_MEMBER( via5_irq_w );

	DECLARE_READ8_MEMBER( via6_pa_r );
	DECLARE_READ8_MEMBER( via6_pb_r );
	DECLARE_WRITE8_MEMBER( via6_pa_w );
	DECLARE_WRITE8_MEMBER( via6_pb_w );
	DECLARE_WRITE_LINE_MEMBER( drw_w );
	DECLARE_WRITE_LINE_MEMBER( erase_w );
	DECLARE_WRITE_LINE_MEMBER( via6_irq_w );

protected:
	// device-level overrides
	virtual void device_start();
	virtual void device_reset();
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);

	// optional information overrides
	virtual const rom_entry *device_rom_region() const;
	virtual machine_config_constructor device_mconfig_additions() const;

private:
	static const int rpm[0x100];

	enum
	{
		TM_GEN,
		TM_TACH0,
		TM_TACH1
	};

	enum
	{
		LED_A = 0,
		LED_B
	};

	enum {
		IDLE,
		RUNNING,
		RUNNING_SYNCPOINT
	};

	struct live_info {
		attotime tm;
		int state, next_state;

		int drive;
		int side;
		int drw;

		// common
		offs_t i;
		UINT8 e;

		// read
		UINT16 shift_reg;
		int bit_counter;
		int sync_bit_counter;
		int sync_byte_counter;
		int brdy;
		bool lbrdy_changed;
		int sync;
		int syn;
		bool syn_changed;
		int gcr_err;

		// write
		UINT16 shift_reg_write;
		UINT8 wd;
		int wrsync;
		int gcr_data;
		int erase;
	};

	devcb_write_line m_irq_cb;
	devcb_write_line m_syn_cb;
	devcb_write_line m_lbrdy_cb;

	required_device<cpu_device> m_maincpu;
	required_device<via6522_device> m_via4;
	required_device<via6522_device> m_via5;
	required_device<via6522_device> m_via6;
	required_device<floppy_image_device> m_floppy0;
	required_device<floppy_image_device> m_floppy1;
	required_memory_region m_gcr_rom;

	void update_stepper_motor(floppy_image_device *floppy, int stp, int old_st, int st);
	void update_spindle_motor(floppy_image_device *floppy, emu_timer *t_tach, bool start, bool stop, bool sel, UINT8 &da);
	void set_rdy0(int state);
	void set_rdy1(int state);

	int load0_cb(floppy_image_device *device);
	void unload0_cb(floppy_image_device *device);

	int load1_cb(floppy_image_device *device);
	void unload1_cb(floppy_image_device *device);

	UINT8 m_p2;

	/* floppy state */
	UINT8 m_da;
	UINT8 m_da0;
	UINT8 m_da1;
	int m_start0;
	int m_stop0;
	int m_start1;
	int m_stop1;
	int m_sel0;
	int m_sel1;
	int m_tach0;
	int m_tach1;
	int m_rdy0;
	int m_rdy1;
	UINT8 m_l0ms;
	UINT8 m_l1ms;
	int m_st0;
	int m_st1;
	int m_stp0;
	int m_stp1;
	int m_drive;
	int m_side;
	int m_drw;
	int m_erase;
	UINT8 m_wd;
	int m_wrsync;

	int m_via4_irq;
	int m_via5_irq;
	int m_via6_irq;

	attotime m_period;

	live_info cur_live, checkpoint_live;
	fdc_pll_t cur_pll, checkpoint_pll;
	emu_timer *t_gen, *t_tach0, *t_tach1;

	floppy_image_device* get_floppy();
	void live_start();
	void pll_reset(const attotime &when);
	void pll_start_writing(const attotime &tm);
	void pll_commit(floppy_image_device *floppy, const attotime &tm);
	void pll_stop_writing(floppy_image_device *floppy, const attotime &tm);
	int pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit);
	bool pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit);
	void pll_save_checkpoint();
	void pll_retrieve_checkpoint();
	void checkpoint();
	void rollback();
	void live_delay(int state);
	void live_sync();
	void live_abort();
	void live_run(const attotime &limit = attotime::never);
};



// device type definition
extern const device_type VICTOR_9000_FDC;



#endif