1 // license:BSD-3-Clause
2 // copyright-holders:Olivier Galibert
3 /*********************************************************************
4 
5     Apple IWM floppy disk controller
6 
7 *********************************************************************/
8 #ifndef MAME_MACHINE_IWM_H
9 #define MAME_MACHINE_IWM_H
10 
11 #pragma once
12 
13 #include "applefdintf.h"
14 
15 
16 //**************************************************************************
17 //  TYPE DEFINITIONS
18 //**************************************************************************
19 
20 
21 class iwm_device: public applefdintf_device
22 {
23 public:
24 	// construction/destruction
25 	iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t q3_clock = 0);
iwm_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,XTAL q3_clock)26 	iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, XTAL q3_clock) :
27 		iwm_device(mconfig, tag, owner, clock, q3_clock.value()) {}
28 
29 	virtual u8 read(offs_t offset) override;
30 	virtual void write(offs_t offset, u8 data) override;
31 
32 	virtual void set_floppy(floppy_image_device *floppy) override;
33 	virtual floppy_image_device *get_floppy() const override;
34 
35 protected:
36 	virtual void device_start() override;
37 	virtual void device_reset() override;
38 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
39 
40 private:
41 	enum {
42 		MODE_IDLE,
43 		MODE_ACTIVE, MODE_DELAY, // m_active modes
44 		MODE_READ, MODE_WRITE    // m_rw modes
45 	};
46 
47 	// state machine states
48 	enum {
49 		S_IDLE,
50 		SR_WINDOW_EDGE_0,
51 		SR_WINDOW_EDGE_1,
52 		SW_WINDOW_MIDDLE,
53 		SW_WINDOW_END
54 	};
55 
56 	floppy_image_device *m_floppy;
57 	emu_timer *m_timer;
58 	double m_q3_fclk_ratio, m_fclk_q3_ratio;
59 	u64 m_last_sync, m_next_state_change, m_sync_update, m_async_update;
60 	u64 m_flux_write_start;
61 	std::array<u64, 16> m_flux_write;
62 	u32 m_flux_write_count;
63 	u32 m_q3_clock;
64 	int m_active, m_rw, m_rw_state;
65 	u8 m_data, m_whd, m_mode, m_status, m_control;
66 	u8 m_rsh, m_wsh;
67 
68 	void sync();
69 	u8 control(int offset, u8 data);
70 	u64 time_to_cycles(const attotime &tm) const;
71 	attotime cycles_to_time(u64 cycles) const;
72 	u64 fclk_to_q3(u64 cycles) const;
73 	u64 q3_to_fclk(u64 cycles) const;
74 
75 	void mode_w(u8 data);
76 	void data_w(u8 data);
77 
78 	u64 window_size() const;
79 	u64 half_window_size() const;
80 	u64 read_register_update_delay() const;
81 	u64 write_sync_half_window_size() const;
82 	inline bool is_sync() const;
83 	void flush_write();
84 };
85 
86 DECLARE_DEVICE_TYPE(IWM, iwm_device)
87 
88 #endif  /* MAME_MACHINE_IWM_H */
89