summaryrefslogtreecommitdiffstats
path: root/src/mame/machine/victor9k_fdc.h
blob: 942c8038ac45fcd566fa08be3223d05b168c5bf0 (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
242
243
244
245
246
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Victor 9000 floppy disk controller emulation

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

#ifndef MAME_MACHINE_VICTOR9K_FDC_H
#define MAME_MACHINE_VICTOR9K_FDC_H

#pragma once

#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 = &downcast<victor_9000_fdc_device &>(*device).set_irq_wr_callback(DEVCB_##_write);

#define MCFG_VICTOR_9000_FDC_SYN_CB(_write) \
	devcb = &downcast<victor_9000_fdc_device &>(*device).set_syn_wr_callback(DEVCB_##_write);

#define MCFG_VICTOR_9000_FDC_LBRDY_CB(_write) \
	devcb = &downcast<victor_9000_fdc_device &>(*device).set_lbrdy_wr_callback(DEVCB_##_write);



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

// ======================> victor_9000_fdc_device

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

	template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_syn_wr_callback(Object &&cb) { return m_syn_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_lbrdy_wr_callback(Object &&cb) { return m_lbrdy_cb.set_callback(std::forward<Object>(cb)); }

	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 );

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;

	// optional information overrides
	virtual const tiny_rom_entry *device_rom_region() const override;
	virtual void device_add_mconfig(machine_config &config) override;

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_t e;

		// read
		uint16_t 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_t shift_reg_write;
		uint8_t 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_connector> m_floppy0;
	required_device<floppy_connector> m_floppy1;
	required_memory_region m_gcr_rom;
	output_finder<2> m_led;

	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_t &da);
	void update_rpm(floppy_image_device *floppy, emu_timer *t_tach, bool sel, uint8_t &da);
	void update_rdy();

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

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

	uint8_t m_p2;

	/* floppy state */
	uint8_t m_da;
	uint8_t m_da0;
	uint8_t 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;
	int m_scp_rdy0;
	int m_scp_rdy1;
	int m_via_rdy0;
	int m_via_rdy1;
	uint8_t m_scp_l0ms;
	uint8_t m_scp_l1ms;
	uint8_t m_via_l0ms;
	uint8_t m_via_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_t 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);

	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_READ_LINE_MEMBER( tach0_r );
	DECLARE_READ_LINE_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 );
};



// device type definition
DECLARE_DEVICE_TYPE(VICTOR_9000_FDC, victor_9000_fdc_device)


#endif // MAME_MACHINE_VICTOR9K_FDC_H