]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/ide/testidnt.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / ide / testidnt.c
1
2 #include <stdio.h>
3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <malloc.h>
8 #include <ctype.h>
9 #include <fcntl.h>
10 #include <dos.h>
11
12 #include <hw/vga/vga.h>
13 #include <hw/pci/pci.h>
14 #include <hw/dos/dos.h>
15 #include <hw/8254/8254.h>               /* 8254 timer */
16 #include <hw/8259/8259.h>               /* 8259 PIC interrupts */
17 #include <hw/vga/vgagui.h>
18 #include <hw/vga/vgatty.h>
19 #include <hw/ide/idelib.h>
20
21 #include "testutil.h"
22 #include "testmbox.h"
23 #include "testcmui.h"
24 #include "testbusy.h"
25 #include "testpiot.h"
26 #include "testrvfy.h"
27 #include "testrdwr.h"
28 #include "testidnt.h"
29 #include "test.h"
30
31 #include "testnop.h"
32 #include "testpwr.h"
33
34 int do_ide_media_card_pass_through(struct ide_controller *ide,unsigned char which,unsigned char enable) {
35         struct ide_taskfile *tsk;
36
37         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
38                 return -1;
39
40         tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
41         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
42         idelib_controller_reset_irq_counter(ide);
43         tsk->features = (enable != 0 ? 1 : 0);
44         idelib_controller_apply_taskfile(ide,0x02/*base_io+1*/,IDELIB_TASKFILE_LBA48_UPDATE|IDELIB_TASKFILE_LBA48);
45         idelib_controller_write_command(ide,0xD1); /* <- (D1h) CHECK MEDIA CARD TYPE */
46         if (ide->flags.io_irq_enable) {
47                 do_ide_controller_user_wait_irq(ide,1);
48                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
49         }
50         do_ide_controller_user_wait_busy_controller(ide);
51         do_ide_controller_user_wait_drive_ready(ide);
52         if (ide->last_status&1) return 1;
53         return 0;
54 }
55
56 int do_ide_set_multiple_mode(struct ide_controller *ide,unsigned char which,unsigned char sz) {
57         struct ide_taskfile *tsk;
58
59         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
60                 return -1;
61
62         tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
63         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
64         idelib_controller_reset_irq_counter(ide);
65         tsk->sector_count = sz;
66         idelib_controller_apply_taskfile(ide,0x04/*base_io+2*/,IDELIB_TASKFILE_LBA48_UPDATE/*clear LBA48*/);
67         idelib_controller_write_command(ide,0xC6); /* <- (C6h) SET MULTIPLE MODE */
68         if (ide->flags.io_irq_enable) {
69                 do_ide_controller_user_wait_irq(ide,1);
70                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
71         }
72         do_ide_controller_user_wait_busy_controller(ide);
73         do_ide_controller_user_wait_drive_ready(ide);
74         if (ide->last_status&1) return 1;
75         return 0;
76 }
77
78 int do_ide_identify(unsigned char *info/*512*/,unsigned int sz,struct ide_controller *ide,unsigned char which,unsigned char command) {
79         if (sz < 512)
80                 return -1;
81         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
82                 return -1;
83
84         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
85         idelib_controller_reset_irq_counter(ide);
86         idelib_controller_write_command(ide,command); /* <- (A1h) identify packet device (ECh) identify device */
87         if (ide->flags.io_irq_enable) {
88                 do_ide_controller_user_wait_irq(ide,1);
89                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
90         }
91         do_ide_controller_user_wait_busy_controller(ide);
92         do_ide_controller_user_wait_drive_ready(ide);
93         if (ide->last_status&1) return 1;
94
95         /* read it */
96         do_ide_controller_user_wait_drive_drq(ide);
97         idelib_read_pio_general((unsigned char*)info,512,ide,IDELIB_PIO_WIDTH_DEFAULT);
98         return 0;
99 }
100
101 int do_ide_flush(struct ide_controller *ide,unsigned char which,unsigned char lba48) {
102         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
103                 return -1;
104
105         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
106         idelib_controller_reset_irq_counter(ide);
107         idelib_controller_write_command(ide,lba48?0xEA:0xE7); /* <- (E7h) FLUSH CACHE (EA) FLUSH CACHE EXT */
108         if (ide->flags.io_irq_enable) {
109                 do_ide_controller_user_wait_irq(ide,1);
110                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
111         }
112         do_ide_controller_user_wait_busy_controller(ide);
113         do_ide_controller_user_wait_drive_ready(ide);
114         if (ide->last_status&1) return 1;
115         return 0;
116 }
117         
118 int do_ide_device_diagnostic(struct ide_controller *ide,unsigned char which) {
119         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
120                 return -1;
121
122         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
123         idelib_controller_reset_irq_counter(ide);
124         idelib_controller_write_command(ide,0x90); /* <- (90h) EXECUTE DEVICE DIAGNOSTIC */
125         if (ide->flags.io_irq_enable) {
126                 do_ide_controller_user_wait_irq(ide,1);
127                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
128         }
129         do_ide_controller_user_wait_busy_controller(ide);
130         do_ide_controller_user_wait_drive_ready(ide);
131         if (ide->last_status&1) return 1;
132         return 0;
133 }
134
135 void do_ident_save(const char *basename,struct ide_controller *ide,unsigned char which,uint16_t *nfo/*512 bytes/256 words*/,unsigned char command) {
136         unsigned char range[512];
137         unsigned char orgl;
138         char fname[24];
139         int fd,r;
140
141         /* also record how the drive records SET MULTIPLE MODE */
142         orgl = nfo[59]&0xFF;
143         vga_write("Scanning SET MULTIPLE MODE supported values\n");
144         for (r=0;r < 256;r++) {
145                 /* set sector count, then use IDENTIFY DEVICE to read back the value */
146                 if (do_ide_set_multiple_mode(ide,which,r) < 0)
147                         break;
148                 if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
149                         break;
150                 range[r] = nfo[59]&0xFF;
151
152                 /* then set it back to "1" */
153                 if (do_ide_set_multiple_mode(ide,which,1) < 0)
154                         break;
155                 if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
156                         break;
157                 range[r+256] = nfo[59]&0xFF;
158
159                 vga_write(".");
160         }
161         vga_write("\n");
162
163         /* restore the original value */
164         if (do_ide_set_multiple_mode(ide,which,orgl) < 0)
165                 return;
166         if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
167                 return;
168
169         /* we might be running off the IDE drive we're about to write to.
170          * so to avoid hangups in INT 13h and DOS we need to temporarily unhook the IRQ and
171          * reenable the IRQ for the BIOS */
172         do_ide_controller_enable_irq(ide,0);
173         idelib_enable_interrupt(ide,1); /* <- in case of stupid/lazy BIOS */
174
175         /* if SMARTDRV is resident, now is a good time to write to disk */
176         if (smartdrv_version != 0) {
177                 for (r=0;r < 4;r++) smartdrv_flush();
178         }
179
180         /* OK. start writing */
181         sprintf(fname,"%s.ID",basename);
182         fd = open(fname,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666);
183         if (fd >= 0) {
184                 write(fd,nfo,512);
185                 close(fd);
186         }
187
188         sprintf(fname,"%s.SMM",basename);
189         fd = open(fname,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666);
190         if (fd >= 0) {
191                 write(fd,range,512);
192                 close(fd);
193         }
194
195         /* if SMARTDRV is resident, flush our snapshot to disk because we're going
196          * to take over the IDE controller again */
197         if (smartdrv_version != 0) {
198                 for (r=0;r < 4;r++) smartdrv_flush();
199         }
200
201         /* OK. hook it again. */
202         do_ide_controller_enable_irq(ide,ide->flags.io_irq_enable);
203 }
204
205 void do_drive_identify_device_test(struct ide_controller *ide,unsigned char which,unsigned char command) {
206         unsigned int x,y,i;
207         uint16_t info[256];
208         int r;
209
210         r = do_ide_identify((unsigned char*)info,sizeof(info),ide,which,command);
211         if (r == 0) {
212                 /* ------------ PAGE 1 -------------*/
213                 vga_write_color(0x0E); vga_clear();
214
215                 vga_moveto(0,0); vga_write("Serial: ");
216                 for (x=0;x < 10;x++) {
217                         tmp[x*2 + 0] = info[10+x] >> 8;
218                         tmp[x*2 + 1] = info[10+x] & 0xFF;
219                 }
220                 tmp[10*2] = 0; vga_write(tmp);
221
222                 vga_write(" F/W rev: ");
223                 for (x=0;x < 4;x++) {
224                         tmp[x*2 + 0] = info[23+x] >> 8;
225                         tmp[x*2 + 1] = info[23+x] & 0xFF;
226                 }
227                 tmp[4*2] = 0; vga_write(tmp);
228
229                 vga_write(" Model: ");
230                 for (x=0;x < 20;x++) {
231                         tmp[x*2 + 0] = info[27+x] >> 8;
232                         tmp[x*2 + 1] = info[27+x] & 0xFF;
233                 }
234                 tmp[20*2] = 0; vga_write(tmp);
235
236                 vga_moveto(0,1);
237                 sprintf(tmp,"Logical C/H/S: %u/%u/%u  ",info[1],info[3],info[6]);
238                 vga_write(tmp);
239                 sprintf(tmp,"Current C/H/S: %u/%u/%u",  info[54],info[55],info[56]);
240                 vga_write(tmp);
241
242                 vga_moveto(0,2);
243                 sprintf(tmp,"Current Capacity: %lu  Total user addressable: %lu",
244                         (unsigned long)info[57] | ((unsigned long)info[58] << 16UL),
245                         (unsigned long)info[60] | ((unsigned long)info[61] << 16UL));
246                 vga_write(tmp);
247
248                 vga_moveto(0,3);
249                 sprintf(tmp,"LBA48 capacity: %llu",
250                         (unsigned long long)info[100] | ((unsigned long long)info[101] << 16ULL) | ((unsigned long long)info[102] << 32ULL) | ((unsigned long long)info[103] << 48ULL));
251                 vga_write(tmp);
252
253                 vga_moveto(0,4);
254                 vga_write_color(0x0D);
255                 vga_write("For more information read ATA documentation. ENTER to continue, 'S' to save.");
256
257                 /* top row */
258                 vga_moveto(0,5);
259                 vga_write_color(0x08);
260                 vga_write("WORD ");
261
262                 vga_moveto(5,5);
263                 for (x=0;x < 8;x++) {
264                         sprintf(tmp,"+%u   ",x);
265                         vga_write(tmp);
266                 }
267                 vga_moveto(46,5);
268                 for (x=0;x < 8;x++) {
269                         sprintf(tmp,"%u ",x);
270                         vga_write(tmp);
271                 }
272                 vga_write("HI/LO byte order");
273
274                 /* data, page by page */
275                 for (i=0;i < 2;i++) {
276                         for (y=0;y < 16;y++) {
277                                 vga_moveto(0,6+y);
278                                 vga_write_color(0x08);
279                                 for (x=0;x < 8;x++) {
280                                         sprintf(tmp,"%04x ",(y*8)+(i*128)+x);
281                                         vga_write(tmp);
282                                 }
283
284                                 vga_moveto(5,6+y);
285                                 vga_write_color(0x0F);
286                                 for (x=0;x < 8;x++) {
287                                         sprintf(tmp,"%04x ",info[(y*8)+(i*128)+x]);
288                                         vga_write(tmp);
289                                 }
290
291                                 vga_moveto(46,6+y);
292                                 vga_write_color(0x0E);
293                                 for (x=0;x < 8;x++) {
294                                         vga_writec(sanitizechar(info[(y*8)+(i*128)+x] >> 8));
295                                         vga_writec(sanitizechar(info[(y*8)+(i*128)+x] & 0xFF));
296                                 }
297                         }
298
299                         /* wait for ENTER, ESC, or 'S' */
300                         do {
301                                 r=getch();
302                                 if (r == 's' || r == 'S') {
303                                         vga_write_color(0x0E); vga_clear(); vga_moveto(0,0); 
304                                         do_ident_save(command == 0xA1 ? "ATAPI" : "ATA",ide,which,info,command);
305                                         vga_write("\nSaved. Hit ENTER to continue.\n");
306                                         wait_for_enter_or_escape();
307                                         break;
308                                 }
309                                 else if (r == 27 || r == 13) {
310                                         break;
311                                 }
312                         } while (1);
313
314                         /* ESC or 'S' to break out */
315                         if (r == 's' || r == 27)
316                                 break;
317                 }
318         }
319         else if (r > 0) {
320                 struct vga_msg_box vgabox;
321
322                 common_ide_success_or_error_vga_msg_box(ide,&vgabox);
323                 wait_for_enter_or_escape();
324                 vga_msg_box_destroy(&vgabox);
325         }
326 }
327