Rev 883 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #pragma once |
2 | struct ATA_DEVICE |
||
3 | { |
||
4 | // ��������� ����� |
||
5 | unsigned c,h,s; |
||
6 | u64 lba; |
||
7 | |||
8 | // ������� ������� �� ����� |
||
9 | u64 lba_cur; // ������� ������ � lba ������ |
||
10 | unsigned c_cur; // ������� ������� |
||
11 | unsigned h_cur; // ������� ������� |
||
12 | unsigned s_cur; // ������� ������ |
||
13 | unsigned n_cur; // ����� �������� |
||
14 | |||
15 | #pragma pack(push, 1) |
||
16 | // �������� (control block) |
||
17 | // ������ (CPU<-HDD) ������ (CPU->HDD) |
||
18 | // 110 | alternate status | device control |
||
19 | // 111 | drive address | not used |
||
20 | |||
21 | // �������� (command block) |
||
22 | // ������ (CPU<-HDD) ������ (CPU->HDD) |
||
23 | // 000 | data | data |
||
24 | // 001 | error | features |
||
25 | // 010 | sector count | sector count |
||
26 | // 011 | sector number | sector number |
||
27 | // | lba [7:0] | lba [7:0] |
||
28 | // 100 | cylinder low | cylinder low |
||
29 | // | lba [15:8] | lba [15:8] |
||
30 | // 101 | cylinder high | cylinder high |
||
31 | // | lba [23:16] | lba [23:16] |
||
32 | // 110 | drive/head | drive/head |
||
33 | // | lba [27:24] | lba [27:24] |
||
34 | // 111 | status | command |
||
35 | |||
36 | struct |
||
37 | { |
||
38 | u8 data; |
||
39 | u8 err; // for write, features |
||
40 | union |
||
41 | { |
||
42 | u8 count; |
||
43 | u8 intreason; |
||
44 | }; |
||
45 | |||
46 | struct |
||
47 | { |
||
48 | union |
||
49 | { |
||
50 | u8 sec; |
||
51 | u8 lba0; |
||
52 | }; |
||
53 | union |
||
54 | { |
||
55 | u16 cyl; |
||
56 | u16 atapi_count; |
||
57 | struct |
||
58 | { |
||
59 | u8 cyl_l; |
||
60 | u8 cyl_h; |
||
61 | }; |
||
62 | struct |
||
63 | { |
||
64 | u8 lba1; |
||
65 | u8 lba2; |
||
66 | }; |
||
67 | u16 lba12; |
||
68 | }; |
||
69 | union |
||
70 | { |
||
71 | u8 devhead; |
||
72 | u8 lba3; // ������ ��� lba28 |
||
73 | }; |
||
74 | }; |
||
75 | |||
76 | u8 status; // for write, cmd |
||
77 | /* */ |
||
78 | u8 control; // reg8 - control (CS1,DA=6) |
||
79 | u8 feat; |
||
80 | u8 cmd; |
||
81 | u8 reserved; // reserved |
||
82 | |||
83 | // ������ ��� lba48 |
||
84 | u8 lba4; |
||
85 | u8 lba5; |
||
86 | u8 lba6; |
||
87 | u8 count1; |
||
88 | } reg; |
||
89 | #pragma pack(pop) |
||
90 | |||
91 | u8 *regs_w[2][9]; // �������� ��� ������ |
||
92 | u8 *regs_r[2][9]; // �������� ��� ������ |
||
93 | unsigned regs_sel; // ������� ���� ��������� ��� lba48 (0/1) |
||
94 | |||
95 | unsigned char intrq; |
||
96 | unsigned char readonly; |
||
97 | unsigned char device_id; // 0x00 - master, 0x10 - slave |
||
98 | unsigned char atapi; // flag for CD-ROM device |
||
99 | |||
100 | ATA_DEVICE() |
||
101 | { |
||
102 | regs_w[0][0] = ®.data; |
||
103 | regs_w[0][1] = ®.feat; |
||
104 | regs_w[0][2] = ®.count; |
||
105 | regs_w[0][3] = ®.lba0; |
||
106 | regs_w[0][4] = ®.lba1; |
||
107 | regs_w[0][5] = ®.lba2; |
||
108 | regs_w[0][6] = ®.devhead; |
||
109 | regs_w[0][7] = ®.cmd; |
||
110 | regs_w[0][8] = ®.control; |
||
111 | |||
112 | regs_w[1][0] = ®.data; |
||
113 | regs_w[1][1] = ®.feat; |
||
114 | regs_w[1][2] = ®.count1; |
||
115 | regs_w[1][3] = ®.lba4; |
||
116 | regs_w[1][4] = ®.lba5; |
||
117 | regs_w[1][5] = ®.lba6; |
||
118 | regs_w[1][6] = ®.devhead; |
||
119 | regs_w[1][7] = ®.cmd; |
||
120 | regs_w[1][8] = ®.control; |
||
121 | |||
122 | regs_r[0][0] = ®.data; |
||
123 | regs_r[0][1] = ®.err; |
||
124 | regs_r[0][2] = ®.count; |
||
125 | regs_r[0][3] = ®.lba0; |
||
126 | regs_r[0][4] = ®.lba1; |
||
127 | regs_r[0][5] = ®.lba2; |
||
128 | regs_r[0][6] = ®.devhead; |
||
129 | regs_r[0][7] = ®.status; |
||
130 | regs_r[0][8] = ®.status; |
||
131 | |||
132 | regs_r[1][0] = ®.data; |
||
133 | regs_r[1][1] = ®.err; |
||
134 | regs_r[1][2] = ®.count1; |
||
135 | regs_r[1][3] = ®.lba4; |
||
136 | regs_r[1][4] = ®.lba5; |
||
137 | regs_r[1][5] = ®.lba6; |
||
138 | regs_r[1][6] = ®.devhead; |
||
139 | regs_r[1][7] = ®.status; |
||
140 | regs_r[1][8] = ®.status; |
||
141 | |||
142 | regs_sel = 0; |
||
143 | } |
||
144 | |||
145 | unsigned char read(unsigned n_reg); |
||
146 | void write(unsigned n_reg, unsigned char data); |
||
147 | unsigned read_data(); |
||
148 | void write_data(unsigned data); |
||
149 | unsigned char read_intrq(); |
||
150 | |||
151 | void update_regs(); // ���������� ��������� � ������������ � �������� ����������� ���������� chs/lba (��� ������ ���������) |
||
152 | void update_cur(); // ���������� ������� ���������� �������� chs/lba � ������������ � ������� � ��������� (��� ������ � ��������) |
||
153 | |||
154 | char exec_ata_cmd(unsigned char cmd); |
||
155 | char exec_atapi_cmd(unsigned char cmd); |
||
156 | |||
157 | enum RESET_TYPE { RESET_HARD, RESET_SOFT, RESET_SRST }; |
||
158 | void reset_signature(RESET_TYPE mode = RESET_SOFT); |
||
159 | |||
160 | void reset(RESET_TYPE mode); |
||
161 | char seek(); |
||
162 | void recalibrate(); |
||
163 | void configure(IDE_CONFIG *cfg); |
||
164 | void prepare_id(); |
||
165 | void command_ok(); |
||
166 | void next_sector(); |
||
167 | void read_sectors(); |
||
168 | void verify_sectors(); |
||
169 | void write_sectors(); |
||
170 | void format_track(); |
||
171 | |||
172 | enum ATAPI_INT_REASON |
||
173 | { |
||
174 | INT_COD = 0x01, |
||
175 | INT_IO = 0x02, |
||
176 | INT_RELEASE = 0x04 |
||
177 | }; |
||
178 | |||
179 | enum HD_STATUS |
||
180 | { |
||
181 | STATUS_BSY = 0x80, |
||
182 | STATUS_DRDY = 0x40, |
||
183 | STATUS_DF = 0x20, |
||
184 | STATUS_DSC = 0x10, |
||
185 | STATUS_DRQ = 0x08, |
||
186 | STATUS_CORR = 0x04, |
||
187 | STATUS_IDX = 0x02, |
||
188 | STATUS_ERR = 0x01 |
||
189 | }; |
||
190 | |||
191 | enum HD_ERROR |
||
192 | { |
||
193 | ERR_BBK = 0x80, |
||
194 | ERR_UNC = 0x40, |
||
195 | ERR_MC = 0x20, |
||
196 | ERR_IDNF = 0x10, |
||
197 | ERR_MCR = 0x08, |
||
198 | ERR_ABRT = 0x04, |
||
199 | ERR_TK0NF = 0x02, |
||
200 | ERR_AMNF = 0x01 |
||
201 | }; |
||
202 | |||
203 | enum HD_CONTROL |
||
204 | { |
||
205 | CONTROL_HOB = 0x80, // ATA-6 |
||
206 | CONTROL_SRST = 0x04, |
||
207 | CONTROL_nIEN = 0x02 |
||
208 | }; |
||
209 | |||
210 | enum HD_STATE |
||
211 | { |
||
212 | S_IDLE = 0, S_READ_ID, |
||
213 | S_READ_SECTORS, S_VERIFY_SECTORS, S_WRITE_SECTORS, S_FORMAT_TRACK, |
||
214 | S_RECV_PACKET, S_READ_ATAPI, |
||
215 | S_MODE_SELECT |
||
216 | }; |
||
217 | |||
218 | HD_STATE state; |
||
219 | unsigned transptr, transcount; |
||
220 | unsigned phys_dev; |
||
221 | unsigned char transbf[0xFFFF]; // ATAPI is able to tranfer 0xFFFF bytes. passing more leads to error |
||
222 | |||
223 | void handle_atapi_packet(); |
||
224 | void handle_atapi_packet_emulate(); |
||
225 | void exec_mode_select(); |
||
226 | |||
227 | ATA_PASSER ata_p; |
||
228 | ATAPI_PASSER atapi_p; |
||
229 | bool loaded() { return ata_p.loaded() || atapi_p.loaded(); } //was crashed at atapi_p.loaded() if no master or slave device!!! see fix in ATAPI_PASSER //Alone Coder |
||
230 | bool selected() { return !((reg.devhead ^ device_id) & 0x10); } |
||
231 | }; |
||
232 | |||
233 | struct ATA_PORT |
||
234 | { |
||
235 | ATA_DEVICE dev[2]; |
||
236 | unsigned char read_high, write_high; |
||
237 | |||
238 | ATA_PORT() |
||
239 | { |
||
240 | dev[0].device_id = 0; |
||
241 | dev[1].device_id = 0x10; |
||
242 | reset(); |
||
243 | } |
||
244 | |||
245 | unsigned char read(unsigned n_reg); |
||
246 | void write(unsigned n_reg, unsigned char data); |
||
247 | unsigned read_data(); |
||
248 | void write_data(unsigned data); |
||
249 | unsigned char read_intrq(); |
||
250 | |||
251 | void reset(); |
||
252 | }; |
||
253 | |||
254 | extern PHYS_DEVICE phys[]; |
||
784 | DimkaM | 255 | extern unsigned n_phys; |
716 | lvd | 256 | |
257 | unsigned find_hdd_device(char *name); |
||
258 | void init_hdd_cd(); |