1 // license:BSD-3-Clause
2 // copyright-holders:smf
3 /***************************************************************************
4 
5     atahle.h
6 
7     ATA Device HLE
8 
9 ***************************************************************************/
10 
11 #ifndef MAME_BUS_ATA_ATAHLE_H
12 #define MAME_BUS_ATA_ATAHLE_H
13 
14 #pragma once
15 
16 #include "atadev.h"
17 
18 class ata_hle_device : public device_t, public device_ata_interface
19 {
20 public:
21 	virtual uint16_t read_dma() override;
22 	virtual uint16_t read_cs0(offs_t offset, uint16_t mem_mask = 0xffff) override;
23 	virtual uint16_t read_cs1(offs_t offset, uint16_t mem_mask = 0xffff) override;
24 
25 	virtual void write_dma(uint16_t data) override;
26 	virtual void write_cs0(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff) override;
27 	virtual void write_cs1(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff) override;
28 	virtual DECLARE_WRITE_LINE_MEMBER(write_csel) override;
29 	virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) override;
30 	virtual DECLARE_WRITE_LINE_MEMBER(write_dmack) override;
31 	virtual DECLARE_WRITE_LINE_MEMBER(write_pdiag) override;
32 
33 protected:
34 	ata_hle_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
35 
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 	void set_irq(int state);
41 	void set_dmarq(int state);
42 	void set_dasp(int state);
43 	void set_pdiag(int state);
44 
45 	void start_busy(const attotime &time, int param);
46 	void stop_busy();
47 
dev()48 	int dev() { return (m_device_head & IDE_DEVICE_HEAD_DRV) >> 4; }
device_selected()49 	bool device_selected() { return m_csel == dev(); }
50 
calculate_status()51 	virtual uint8_t calculate_status() { return m_status; }
52 	virtual void soft_reset();
53 	virtual void process_command();
54 	virtual void finished_command();
55 	virtual bool set_features();
56 	virtual int sector_length() = 0;
57 	virtual void process_buffer() = 0;
58 	virtual void fill_buffer() = 0;
59 	virtual bool is_ready() = 0;
60 	virtual void perform_diagnostic() = 0;
61 	virtual void signature() = 0;
62 	virtual uint16_t read_data();
63 	virtual void write_data(uint16_t data);
64 
65 	int bit_to_mode(uint16_t word);
66 	int single_word_dma_mode();
67 	int multi_word_dma_mode();
68 	int ultra_dma_mode();
69 
70 	/// TODO: not sure this should be protected.
71 	void read_buffer_empty();
72 
73 	enum
74 	{
75 		IDE_STATUS_ERR = 0x01, // Error
76 		IDE_STATUS_IDX = 0x02, // Index
77 		IDE_STATUS_CORR = 0x04, // Corrected Data
78 		IDE_STATUS_DRQ = 0x08, // Data Request
79 		IDE_STATUS_DSC = 0x10, // ATA Drive Seek Complete
80 		IDE_STATUS_SERV = 0x10, // ATAPI Service
81 		IDE_STATUS_DWF = 0x20, // ATA Drive Write Fault
82 		IDE_STATUS_DMRD = 0x20, // ATAPI DMA Ready
83 		IDE_STATUS_DRDY = 0x40, // Drive Ready
84 		IDE_STATUS_BSY = 0x80 // Busy
85 	};
86 
87 	enum
88 	{
89 		IDE_ERROR_NONE = 0x00,
90 		IDE_ERROR_DIAGNOSTIC_OK = 0x01,
91 		IDE_ERROR_TRACK0_NOT_FOUND = 0x02,
92 		IDE_ERROR_ABRT = 0x04,
93 		IDE_ERROR_BAD_LOCATION = 0x10,
94 		IDE_ERROR_BAD_SECTOR = 0x80,
95 		IDE_ERROR_DIAGNOSTIC_FAILED = 0x00,
96 		IDE_ERROR_DIAGNOSTIC_PASSED = 0x01,
97 		IDE_ERROR_DIAGNOSTIC_DEVICE1_FAILED = 0x80
98 	};
99 
100 	enum
101 	{
102 		IDE_COMMAND_NOP = 0x00,
103 		IDE_COMMAND_DEVICE_RESET = 0x08,
104 		IDE_COMMAND_RECALIBRATE = 0x10,
105 		IDE_COMMAND_READ_SECTORS = 0x20,
106 		IDE_COMMAND_READ_SECTORS_NORETRY = 0x21,
107 		IDE_COMMAND_WRITE_SECTORS = 0x30,
108 		IDE_COMMAND_WRITE_SECTORS_NORETRY = 0x31,
109 		IDE_COMMAND_VERIFY_SECTORS = 0x40,
110 		IDE_COMMAND_VERIFY_SECTORS_NORETRY = 0x41,
111 		IDE_COMMAND_SEEK = 0x70,
112 		IDE_COMMAND_DIAGNOSTIC = 0x90,
113 		IDE_COMMAND_SET_CONFIG = 0x91,
114 		IDE_COMMAND_PACKET = 0xa0,
115 		IDE_COMMAND_IDENTIFY_PACKET_DEVICE = 0xa1,
116 		IDE_COMMAND_READ_MULTIPLE = 0xc4,
117 		IDE_COMMAND_WRITE_MULTIPLE = 0xc5,
118 		IDE_COMMAND_SET_BLOCK_COUNT = 0xc6,
119 		IDE_COMMAND_READ_DMA = 0xc8,
120 		IDE_COMMAND_WRITE_DMA = 0xca,
121 		IDE_COMMAND_IDLE_IMMEDIATE = 0xe1,
122 		IDE_COMMAND_IDLE = 0xe3,
123 		IDE_COMMAND_CHECK_POWER_MODE = 0xe5,
124 		IDE_COMMAND_CACHE_FLUSH = 0xe7,
125 		IDE_COMMAND_IDENTIFY_DEVICE = 0xec,
126 		IDE_COMMAND_SET_FEATURES = 0xef,
127 		IDE_COMMAND_SECURITY_UNLOCK = 0xf2,
128 		IDE_COMMAND_SECURITY_DISABLE_PASSWORD = 0xf6,
129 		IDE_COMMAND_READ_NATIVE_MAX_ADDRESS = 0xf8,
130 		IDE_COMMAND_SET_MAX = 0xf9
131 	};
132 
133 	enum
134 	{
135 		IDE_SET_FEATURES_ENABLE_8BIT_DATA_TRANSFERS = 0x01,
136 		IDE_SET_FEATURES_TRANSFER_MODE = 0x03,
137 		IDE_SET_FEATURES_DISABLE_REVERTING_TO_POWER_ON_DEFAULTS = 0x66,
138 		IDE_SET_FEATURES_DISABLE_8BIT_DATA_TRANSFERS = 0x81,
139 		IDE_SET_FEATURES_ENABLE_REVERTING_TO_POWER_ON_DEFAULTS = 0xcc
140 	};
141 
142 	enum ide_transfer_type_t
143 	{
144 		IDE_TRANSFER_TYPE_PIO_DEFAULT = 0x00,
145 		IDE_TRANSFER_TYPE_PIO_FLOW_CONTROL = 0x08,
146 		IDE_TRANSFER_TYPE_SINGLE_WORD_DMA = 0x10,
147 		IDE_TRANSFER_TYPE_MULTI_WORD_DMA = 0x20,
148 		IDE_TRANSFER_TYPE_ULTRA_DMA = 0x40,
149 		IDE_TRANSFER_TYPE_MASK = 0xf8
150 	};
151 
152 	enum
153 	{
154 		IDE_DEVICE_HEAD_HS = 0x0f,
155 		IDE_DEVICE_HEAD_DRV = 0x10,
156 		IDE_DEVICE_HEAD_L = 0x40,
157 		IDE_DEVICE_HEAD_OBSOLETE = 0x80 | 0x20
158 	};
159 
160 	enum
161 	{
162 		TID_BUSY,
163 		TID_BUFFER_EMPTY
164 	};
165 
166 	enum
167 	{
168 		PARAM_RESET,
169 		PARAM_DETECT_DEVICE1,
170 		PARAM_DIAGNOSTIC,
171 		PARAM_WAIT_FOR_PDIAG,
172 		PARAM_COMMAND
173 	};
174 
175 	attotime MINIMUM_COMMAND_TIME;
176 
177 	std::vector<uint8_t> m_buffer;
178 	uint16_t m_buffer_offset;
179 	uint16_t m_buffer_size;
180 	uint8_t m_error;
181 	uint8_t m_feature;
182 	uint16_t m_sector_count;
183 	uint8_t m_sector_number;
184 	uint8_t m_cylinder_low;
185 	uint8_t m_cylinder_high;
186 	uint8_t m_device_head;
187 	uint8_t m_status;
188 	uint8_t m_command;
189 	uint8_t m_device_control;
190 
191 	uint16_t m_identify_buffer[256];
192 	bool m_revert_to_defaults;
193 	bool m_8bit_data_transfers;
194 
195 private:
196 	void update_irq();
197 	void write_buffer_full();
198 	void start_diagnostic();
199 	void finished_diagnostic();
200 	void finished_busy(int param);
201 	bool set_dma_mode(int word);
202 
203 	int m_csel;
204 	int m_daspin;
205 	int m_daspout;
206 	int m_dmack;
207 	int m_dmarq;
208 	int m_irq;
209 	int m_pdiagin;
210 	int m_pdiagout;
211 
212 	bool m_single_device;
213 	bool m_resetting;
214 
215 	emu_timer *m_busy_timer;
216 	emu_timer *m_buffer_empty_timer;
217 };
218 
219 #endif // MAME_BUS_ATA_ATAHLE_H
220