1 // license:BSD-3-Clause
2 // copyright-holders:Carl,Olivier Galibert
3 #ifndef MAME_MACHINE_I8271_H
4 #define MAME_MACHINE_I8271_H
5 
6 #pragma once
7 
8 #include "fdc_pll.h"
9 #include "imagedev/floppy.h"
10 
11 class floppy_image_device;
12 
13 
14 /***************************************************************************
15     MACROS
16 ***************************************************************************/
17 
18 class i8271_device : public device_t
19 {
20 public:
21 	i8271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
22 
intrq_wr_callback()23 	auto intrq_wr_callback() { return intrq_cb.bind(); }
drq_wr_callback()24 	auto drq_wr_callback() { return drq_cb.bind(); }
hdl_wr_callback()25 	auto hdl_wr_callback() { return hdl_cb.bind(); }
opt_wr_callback()26 	auto opt_wr_callback() { return opt_cb.bind(); }
27 
28 	uint8_t read(offs_t offset);
29 	void write(offs_t offset, uint8_t data);
30 	uint8_t data_r();
31 	void data_w(uint8_t data);
32 
33 	void ready_w(bool val);
34 
35 	void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled
36 
37 	void set_ready_line_connected(bool ready);
38 	void set_select_lines_connected(bool select);
39 	void set_floppies(floppy_connector* f0, floppy_connector* f1);
40 	void soft_reset();
41 
42 	void map(address_map &map);
43 
44 protected:
45 	virtual void device_start() override;
46 	virtual void device_reset() override;
47 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
48 
49 private:
50 	enum {
51 		PHASE_IDLE, PHASE_CMD, PHASE_EXEC, PHASE_RESULT
52 	};
53 
54 	enum {
55 		RR_DEL = 0x20,
56 		RR_CT  = 0x18,
57 		RR_CC  = 0x06,
58 
59 		SR_BSY = 0x80,
60 		SR_CF  = 0x40,
61 		SR_PF  = 0x20,
62 		SR_RF  = 0x10,
63 		SR_IRQ = 0x08,
64 		SR_DRQ = 0x04
65 	};
66 
67 	enum {
68 		ERR_NONE = 0x00,
69 		ERR_SMEQ = 0x02,
70 		ERR_SMNE = 0x04,
71 		ERR_CLK  = 0x08,
72 		ERR_DMA  = 0x0a,
73 		ERR_ICRC = 0x0c,
74 		ERR_DCRC = 0x0e,
75 		ERR_NR   = 0x10,
76 		ERR_WP   = 0x12,
77 		ERR_T0NF = 0x14,
78 		ERR_WF   = 0x16,
79 		ERR_NF   = 0x18
80 	};
81 
82 	enum {
83 		// General "doing nothing" state
84 		IDLE,
85 
86 		// Main states
87 		RECALIBRATE,
88 		SEEK,
89 		READ_DATA,
90 		WRITE_DATA,
91 		FORMAT_TRACK,
92 		READ_ID,
93 		SCAN_DATA,
94 		VERIFY_DATA,
95 
96 		// Sub-states
97 		COMMAND_DONE,
98 
99 		SEEK_MOVE,
100 		SEEK_WAIT_STEP_SIGNAL_TIME,
101 		SEEK_WAIT_STEP_SIGNAL_TIME_DONE,
102 		SEEK_WAIT_STEP_TIME,
103 		SEEK_WAIT_STEP_TIME_DONE,
104 		SEEK_DONE,
105 
106 		HEAD_LOAD_DONE,
107 
108 		WAIT_INDEX,
109 		WAIT_INDEX_DONE,
110 
111 		SCAN_ID,
112 		SCAN_ID_FAILED,
113 
114 		SECTOR_READ,
115 		SECTOR_WRITTEN,
116 		TC_DONE,
117 
118 		TRACK_DONE,
119 
120 		// Live states
121 		SEARCH_ADDRESS_MARK_HEADER,
122 		READ_ID_BLOCK,
123 		SEARCH_ADDRESS_MARK_DATA,
124 		SEARCH_ADDRESS_MARK_DATA_FAILED,
125 		READ_SECTOR_DATA,
126 		READ_SECTOR_DATA_BYTE,
127 		SCAN_SECTOR_DATA_BYTE,
128 		VERIFY_SECTOR_DATA_BYTE,
129 
130 		WRITE_SECTOR_SKIP_GAP2,
131 		WRITE_SECTOR_SKIP_GAP2_BYTE,
132 		WRITE_SECTOR_DATA,
133 		WRITE_SECTOR_DATA_BYTE,
134 
135 		WRITE_TRACK_PRE_SECTORS,
136 		WRITE_TRACK_PRE_SECTORS_BYTE,
137 
138 		WRITE_TRACK_SECTOR,
139 		WRITE_TRACK_SECTOR_BYTE,
140 
141 		WRITE_TRACK_POST_SECTORS,
142 		WRITE_TRACK_POST_SECTORS_BYTE
143 	};
144 
145 	struct pll_t {
146 		attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust;
147 
148 		attotime write_start_time;
149 		attotime write_buffer[32];
150 		int write_position;
151 		int freq_hist;
152 
153 		void set_clock(const attotime &period);
154 		void reset(const attotime &when);
155 		int get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit);
156 		bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit);
157 		void start_writing(const attotime &tm);
158 		void commit(floppy_image_device *floppy, const attotime &tm);
159 		void stop_writing(floppy_image_device *floppy, const attotime &tm);
160 	};
161 
162 	struct floppy_info {
163 		enum { IRQ_NONE, IRQ_POLLED, IRQ_SEEK, IRQ_DONE };
164 		emu_timer *tm;
165 		floppy_image_device *dev;
166 		int id;
167 		int main_state, sub_state;
168 		int dir, counter;
169 		uint8_t pcn, badtrack[2];
170 		bool live, index, ready;
171 	};
172 
173 	struct live_info {
174 		enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
175 
176 		attotime tm;
177 		int state, next_state;
178 		floppy_info *fi;
179 		uint16_t shift_reg;
180 		uint16_t crc;
181 		int bit_counter, byte_counter, previous_type;
182 		bool data_separator_phase, data_bit_context;
183 		uint8_t data_reg;
184 		uint8_t idbuf[6];
185 		fdc_pll_t pll;
186 	};
187 
188 	bool ready_connected, select_connected;
189 
190 	bool external_ready;
191 
192 	int mode;
193 	int main_phase;
194 
195 	live_info cur_live, checkpoint_live;
196 	devcb_write_line intrq_cb, drq_cb, hdl_cb, opt_cb;
197 	bool irq, drq, scan_done, scan_match;
198 	floppy_info flopi[2];
199 
200 	int command_pos, sectors_read, scan_len;
201 	uint8_t command[6], dma_data, oport;
202 	uint8_t rr, scan_sec, moder;
203 	uint8_t precomp, perpmode, scan_cnt[2];
204 	uint8_t srate, hset, icnt, hload;
205 	int sector_size;
206 	int cur_rate;
207 	int idle_icnt;
208 
209 	static std::string tts(attotime t);
210 	std::string ttsn();
211 
212 	enum {
213 		C_FORMAT_TRACK,
214 		C_READ_DATA_SINGLE,
215 		C_READ_DATA_MULTI,
216 		C_VERIFY_DATA_SINGLE,
217 		C_VERIFY_DATA_MULTI,
218 		C_WRITE_DATA_SINGLE,
219 		C_WRITE_DATA_MULTI,
220 		C_READ_ID,
221 		C_SEEK,
222 		C_READ_DRIVE_STATUS,
223 		C_SPECIFY,
224 		C_SCAN,
225 		C_WRITE_SPECIAL_REGISTER,
226 		C_READ_SPECIAL_REGISTER,
227 
228 		C_INVALID,
229 		C_INCOMPLETE
230 	};
231 
232 	uint8_t sr_r();
233 	uint8_t rr_r();
reset_w(uint8_t data)234 	void reset_w(uint8_t data) { if(data == 1) soft_reset(); }
235 	void cmd_w(uint8_t data);
236 	void param_w(uint8_t data);
237 
238 	void delay_cycles(emu_timer *tm, int cycles);
239 	void set_drq(bool state);
240 	void set_irq(bool state);
241 	bool get_ready(int fid);
242 
243 	int calc_sector_size(uint8_t size);
244 
245 	int check_command();
246 	void start_command(int cmd);
247 	void command_end(floppy_info &fi, bool data_completion);
248 
249 	void recalibrate_start(floppy_info &fi);
250 	void seek_start(floppy_info &fi);
251 	void seek_continue(floppy_info &fi);
252 
253 	void read_data_start(floppy_info &fi);
254 	void read_data_continue(floppy_info &fi);
255 
256 	void write_data_start(floppy_info &fi);
257 	void write_data_continue(floppy_info &fi);
258 
259 	void format_track_start(floppy_info &fi);
260 	void format_track_continue(floppy_info &fi);
261 
262 	void read_id_start(floppy_info &fi);
263 	void read_id_continue(floppy_info &fi);
264 
265 	void scan_start(floppy_info &fi);
266 	void verify_data_start(floppy_info &fi);
267 
268 	void general_continue(floppy_info &fi);
269 	void index_callback(floppy_image_device *floppy, int state);
270 	bool sector_matches() const;
271 
272 	void live_start(floppy_info &fi, int live_state);
273 	void live_abort();
274 	void checkpoint();
275 	void rollback();
276 	void live_delay(int state);
277 	void live_sync();
278 	void live_run(attotime limit = attotime::never);
279 	void live_write_raw(uint16_t raw);
280 	void live_write_fm(uint8_t fm);
281 
282 	bool read_one_bit(const attotime &limit);
283 	bool write_one_bit(const attotime &limit);
284 	bool set_output(uint8_t data);
285 	bool get_input(uint8_t *data);
286 };
287 
288 DECLARE_DEVICE_TYPE(I8271, i8271_device)
289 
290 #endif // MAME_MACHINE_I8271_H
291