]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/ide/testrdwr.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / ide / testrdwr.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 "testcdej.h"
30 #include "testpiom.h"
31 #include "testtadj.h"
32 #include "testcdrm.h"
33 #include "testmumo.h"
34 #include "testrdts.h"
35 #include "testrdtv.h"
36 #include "testrdws.h"
37 #include "test.h"
38
39 #include "testnop.h"
40 #include "testpwr.h"
41
42 const char *drive_readwrite_test_modes[] = {
43         "Mode: C/H/S",
44         "Mode: C/H/S MULTIPLE",
45         "Mode: LBA",
46         "Mode: LBA MULTIPLE",
47         "Mode: LBA48",
48         "Mode: LBA48 MULTIPLE"
49 };
50
51 struct drive_rw_test_info               drive_rw_test_nfo;
52
53 char                                    drive_readwrite_test_geo[128];
54 char                                    drive_readwrite_test_chs[128];
55 char                                    drive_readwrite_test_numsec[128];
56 char                                    drive_readwrite_test_mult[128];
57
58 int drive_rw_test_mode_supported(struct drive_rw_test_info *nfo) {
59         if (!drive_rw_test_nfo.can_do_multiple &&
60                 (nfo->mode == DRIVE_RW_MODE_CHSMULTIPLE ||
61                  nfo->mode == DRIVE_RW_MODE_LBAMULTIPLE ||
62                  nfo->mode == DRIVE_RW_MODE_LBA48_MULTIPLE))
63                 return 0;
64
65         if (!drive_rw_test_nfo.can_do_lba &&
66                 (nfo->mode == DRIVE_RW_MODE_LBA ||
67                  nfo->mode == DRIVE_RW_MODE_LBAMULTIPLE ||
68                  nfo->mode == DRIVE_RW_MODE_LBA48 ||
69                  nfo->mode == DRIVE_RW_MODE_LBA48_MULTIPLE))
70                 return 0;
71
72         if (!drive_rw_test_nfo.can_do_lba48 &&
73                 (nfo->mode == DRIVE_RW_MODE_LBA48 ||
74                  nfo->mode == DRIVE_RW_MODE_LBA48_MULTIPLE))
75                 return 0;
76
77         return 1;
78 }
79
80 void do_drive_readwrite_edit_chslba(struct ide_controller *ide,unsigned char which,struct drive_rw_test_info *nfo,unsigned char editgeo) {
81         uint64_t lba,tmp;
82         int cyl,head,sect;
83         struct vga_msg_box box;
84         unsigned char redraw=1;
85         unsigned char ok=1;
86         char temp_str[64];
87         int select=0;
88         int c,i=0;
89
90         if (editgeo) {
91                 cyl = nfo->num_cylinder;
92                 sect = nfo->num_sector;
93                 head = nfo->num_head;
94                 lba = nfo->max_lba;
95         }
96         else {
97                 cyl = nfo->cylinder;
98                 sect = nfo->sector;
99                 head = nfo->head;
100                 lba = nfo->lba;
101         }
102
103         vga_msg_box_create(&box,editgeo ?
104                 "Edit disk geometry:             " :
105                 "Edit position:                  ",
106                 2+4,0);
107         while (1) {
108                 char recalc = 0;
109                 char rekey = 0;
110
111                 if (redraw) {
112                         redraw = 0;
113
114                         vga_moveto(box.x+2,box.y+2+1 + 0);
115                         vga_write_color(0x1E);
116                         vga_write("Cylinder:  ");
117                         vga_write_color(select == 0 ? 0x70 : 0x1E);
118                         i=sprintf(temp_str,"%u",cyl);
119                         while (i < (box.w-4-11)) temp_str[i++] = ' ';
120                         temp_str[i] = 0;
121                         vga_write(temp_str);
122
123                         vga_moveto(box.x+2,box.y+2+1 + 1);
124                         vga_write_color(0x1E);
125                         vga_write("Head:      ");
126                         vga_write_color(select == 1 ? 0x70 : 0x1E);
127                         i=sprintf(temp_str,"%u",head);
128                         while (i < (box.w-4-11)) temp_str[i++] = ' ';
129                         temp_str[i] = 0;
130                         vga_write(temp_str);
131
132                         vga_moveto(box.x+2,box.y+2+1 + 2);
133                         vga_write_color(0x1E);
134                         vga_write("Sector:    ");
135                         vga_write_color(select == 2 ? 0x70 : 0x1E);
136                         i=sprintf(temp_str,"%u",sect);
137                         while (i < (box.w-4-11)) temp_str[i++] = ' ';
138                         temp_str[i] = 0;
139                         vga_write(temp_str);
140
141                         vga_moveto(box.x+2,box.y+2+1 + 3);
142                         vga_write_color(0x1E);
143                         vga_write("LBA:       ");
144                         vga_write_color(select == 3 ? 0x70 : 0x1E);
145                         i=sprintf(temp_str,"%llu",lba);
146                         while (i < (box.w-4-11)) temp_str[i++] = ' ';
147                         temp_str[i] = 0;
148                         vga_write(temp_str);
149                 }
150
151                 c = getch();
152                 if (c == 0) c = getch() << 8;
153
154 nextkey:        if (c == 27) {
155                         ok = 0;
156                         break;
157                 }
158                 else if (c == 13) {
159                         ok = 1;
160                         break;
161                 }
162                 else if (c == 0x4800) {
163                         if (--select < 0) select = 3;
164                         redraw = 1;
165                 }
166                 else if (c == 0x5000 || c == 9/*tab*/) {
167                         if (++select > 3) select = 0;
168                         redraw = 1;
169                 }
170
171                 else if (c == 0x4B00) { /* left */
172                         switch (select) {
173                                 case 0:
174                                         if (cyl == 0) cyl = editgeo ? 16383 : (nfo->num_cylinder - 1);
175                                         else cyl--;
176                                         break;
177                                 case 1:
178                                         if (head == 0) head = editgeo ? 16 : (nfo->num_head - 1);
179                                         else head--;
180                                         break;
181                                 case 2:
182                                         if (sect <= 1) sect = editgeo ? 256 : nfo->num_sector;
183                                         else sect--;
184                                         break;
185                                 case 3:
186                                         if (lba > 0ULL) lba--;
187                                         break;
188                         };
189
190                         recalc = 1;
191                         redraw = 1;
192                 }
193                 else if (c == 0x4D00) { /* right */
194                         switch (select) {
195                                 case 0:
196                                         if ((++cyl) >= (editgeo ? 16384 : nfo->num_cylinder)) cyl = 0;
197                                         break;
198                                 case 1:
199                                         if ((++head) >= (editgeo ? 17 : nfo->num_head)) head = 0;
200                                         break;
201                                 case 2:
202                                         if ((++sect) >= (editgeo ? 257 : (nfo->num_sector+1))) sect = 1;
203                                         break;
204                                 case 3:
205                                         lba++;
206                                         break;
207                         };
208
209                         recalc = 1;
210                         redraw = 1;
211                 }
212
213                 else if (c == 8 || isdigit(c)) {
214                         unsigned int sy = box.y+2+1 + select;
215                         unsigned int sx = box.x+2+11;
216
217                         switch (select) {
218                                 case 0: sprintf(temp_str,"%u",cyl); break;
219                                 case 1: sprintf(temp_str,"%u",head); break;
220                                 case 2: sprintf(temp_str,"%u",sect); break;
221                                 case 3: sprintf(temp_str,"%llu",lba); break;
222                         }
223
224                         if (c == 8) {
225                                 i = strlen(temp_str) - 1;
226                                 if (i < 0) i = 0;
227                                 temp_str[i] = 0;
228                         }
229                         else {
230                                 i = strlen(temp_str);
231                                 if (i == 1 && temp_str[0] == '0') i--;
232                                 if ((i+2) < sizeof(temp_str)) {
233                                         temp_str[i++] = (char)c;
234                                         temp_str[i] = 0;
235                                 }
236                         }
237
238                         redraw = 1;
239                         while (1) {
240                                 if (redraw) {
241                                         redraw = 0;
242                                         vga_moveto(sx,sy);
243                                         vga_write_color(0x70);
244                                         vga_write(temp_str);
245                                         while (vga_pos_x < (box.x+box.w-4) && vga_pos_x != 0) vga_writec(' ');
246                                 }
247
248                                 c = getch();
249                                 if (c == 0) c = getch() << 8;
250
251                                 if (c == 8) {
252                                         if (i > 0) {
253                                                 temp_str[--i] = 0;
254                                                 redraw = 1;
255                                         }
256                                 }
257                                 else if (isdigit(c)) {
258                                         if ((i+2) < sizeof(temp_str)) {
259                                                 temp_str[i++] = (char)c;
260                                                 temp_str[i] = 0;
261                                                 redraw = 1;
262                                         }
263                                 }
264                                 else {
265                                         break;
266                                 }
267                         }
268
269                         switch (select) {
270                                 case 0: tmp=strtoull(temp_str,NULL,0); cyl=(tmp >  16383ULL ? 16383ULL : tmp); break;
271                                 case 1: tmp=strtoull(temp_str,NULL,0); head=(tmp >    16ULL ?    16ULL : tmp); break;
272                                 case 2: tmp=strtoull(temp_str,NULL,0); sect=(tmp >   256ULL ?   256ULL : tmp); break;
273                                 case 3: lba=strtoull(temp_str,NULL,0); break;
274                         }
275
276                         rekey = 1;
277                         recalc = 1;
278                 }
279
280                 if (recalc) {
281                         recalc = 0;
282                         if (sect == 0) sect = 1;
283                         if (cyl > 16383) cyl = 16383;
284
285                         if (editgeo) {
286                                 if (cyl < 1) cyl = 1;
287                                 if (head < 1) head = 1;
288                                 if (head > 16) head = 16;
289                                 if (sect > 256) sect = 256;
290
291                                 if (select == 3) {
292                                         if (lba >= (16383ULL * 16ULL * 63ULL)) {
293                                                 sect = 63;
294                                                 head = 16;
295                                                 cyl = 16383;
296                                         }
297                                         else {
298                                                 cyl = (int)(lba / (unsigned long long)sect / (unsigned long long)head);
299                                                 if (cyl < 0) cyl = 1;
300                                                 if (cyl > 16383) cyl = 16383;
301                                         }
302                                 }
303                                 else if (cyl < 16383) {
304                                         lba = (unsigned long long)cyl * (unsigned long long)head * (unsigned long long)sect;
305                                 }
306                         }
307                         else {
308                                 if (cyl < 0) cyl = 0;
309                                 if (head < 0) head = 0;
310                                 if (head > 15) head = 15;
311                                 if (sect > 255) sect = 255;
312
313                                 if (select == 3) {
314                                         sect = (int)(lba % (unsigned long long)nfo->num_sector) + 1;
315                                         head = (int)((lba / (unsigned long long)nfo->num_sector) % (unsigned long long)nfo->num_head);
316                                         if (lba >= (16384ULL * (unsigned long long)nfo->num_sector * (unsigned long long)nfo->num_head)) {
317                                                 cyl = 16383;
318                                                 sect = nfo->num_sector;
319                                                 head = nfo->num_head - 1;
320                                         }
321                                         else {
322                                                 cyl = (int)((lba / (unsigned long long)nfo->num_sector) / (unsigned long long)nfo->num_head);
323                                         }
324                                 }
325                                 else {
326                                         lba  = (unsigned long long)cyl * (unsigned long long)nfo->num_sector * (unsigned long long)nfo->num_head;
327                                         lba += (unsigned long long)head * (unsigned long long)nfo->num_sector;
328                                         lba += (unsigned long long)sect - 1ULL;
329                                 }
330                         }
331
332                         redraw = 1;
333                 }
334
335                 if (rekey) {
336                         rekey = 0;
337                         goto nextkey;
338                 }
339         }
340         vga_msg_box_destroy(&box);
341
342         if (ok) {
343                 if (editgeo) {
344                         nfo->num_cylinder = cyl;
345                         nfo->num_sector = sect;
346                         nfo->num_head = head;
347                         nfo->max_lba = lba;
348                 }
349                 else {
350                         nfo->cylinder = cyl;
351                         nfo->sector = sect;
352                         nfo->head = head;
353                         nfo->lba = lba;
354                 }
355         }
356 }
357
358 void do_drive_readwrite_test_choose_mode(struct ide_controller *ide,unsigned char which,struct drive_rw_test_info *nfo) {
359         int select=drive_rw_test_nfo.mode;
360         struct menuboxbounds mbox;
361         char backredraw=1;
362         VGA_ALPHA_PTR vga;
363         unsigned int x,y;
364         char redraw=1;
365         int c;
366
367         /* UI element vars */
368         menuboxbounds_set_def_list(&mbox,/*ofsx=*/4,/*ofsy=*/7,/*cols=*/1);
369         menuboxbounds_set_item_strings_arraylen(&mbox,drive_readwrite_test_modes);
370
371         while (1) {
372                 if (backredraw) {
373                         vga = vga_alpha_ram;
374                         backredraw = 0;
375                         redraw = 1;
376
377                         for (y=0;y < vga_height;y++) {
378                                 for (x=0;x < vga_width;x++) {
379                                         *vga++ = 0x1E00 + 177;
380                                 }
381                         }
382
383                         vga_moveto(0,0);
384
385                         vga_write_color(0x1F);
386                         vga_write("        IDE r/w test mode ");
387                         sprintf(tmp,"@%X",ide->base_io);
388                         vga_write(tmp);
389                         if (ide->alt_io != 0) {
390                                 sprintf(tmp," alt %X",ide->alt_io);
391                                 vga_write(tmp);
392                         }
393                         if (ide->irq >= 0) {
394                                 sprintf(tmp," IRQ %d",ide->irq);
395                                 vga_write(tmp);
396                         }
397                         vga_write(which ? " Slave" : " Master");
398
399                         sprintf(tmp," lba=%u lba48=%u multiple=%u",
400                                 drive_rw_test_nfo.can_do_lba?1:0,
401                                 drive_rw_test_nfo.can_do_lba48?1:0,
402                                 drive_rw_test_nfo.can_do_multiple?1:0);
403                         vga_write(tmp);
404
405                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
406
407                         vga_write_color(0xC);
408                         vga_write("WARNING: This code talks directly to your hard disk controller.");
409                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
410                         vga_write_color(0xC);
411                         vga_write("         If you value the data on your hard drive do not run this program.");
412                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
413                 }
414
415                 if (redraw) {
416                         redraw = 0;
417
418                         vga_moveto(mbox.ofsx,mbox.ofsy - 2);
419                         vga_write_color((select == -1) ? 0x70 : 0x0F);
420                         vga_write("Back");
421                         while (vga_pos_x < (mbox.width+mbox.ofsx) && vga_pos_x != 0) vga_writec(' ');
422
423                         menuboxbound_redraw(&mbox,select);
424                 }
425
426                 c = getch();
427                 if (c == 0) c = getch() << 8;
428
429                 if (c == 27) {
430                         break;
431                 }
432                 else if (c == 13) {
433                         struct vga_msg_box vgabox;
434
435                         if (!drive_rw_test_nfo.can_do_multiple &&
436                                 (select == DRIVE_RW_MODE_CHSMULTIPLE ||
437                                 select == DRIVE_RW_MODE_LBAMULTIPLE ||
438                                 select == DRIVE_RW_MODE_LBA48_MULTIPLE)) {
439
440                                 vga_msg_box_create(&vgabox,
441                                         "The IDE device doesn't seem to support SET MULTIPLE/READ MULTIPLE.\n"
442                                         "Are you sure you want to choose this mode?\n"
443                                         "\n"
444                                         "Hit ENTER to proceed, ESC to cancel"
445                                         ,0,0);
446                                 do {
447                                         c = getch();
448                                         if (c == 0) c = getch() << 8;
449                                 } while (!(c == 13 || c == 27));
450                                 vga_msg_box_destroy(&vgabox);
451                                 if (c == 27) continue;
452                         }
453
454                         if (!drive_rw_test_nfo.can_do_lba &&
455                                 (select == DRIVE_RW_MODE_LBA ||
456                                 select == DRIVE_RW_MODE_LBAMULTIPLE ||
457                                 select == DRIVE_RW_MODE_LBA48 ||
458                                 select == DRIVE_RW_MODE_LBA48_MULTIPLE)) {
459
460                                 vga_msg_box_create(&vgabox,
461                                         "The IDE device doesn't seem to support LBA mode.\n"
462                                         "Are you sure you want to choose this mode?\n"
463                                         "\n"
464                                         "Hit ENTER to proceed, ESC to cancel"
465                                         ,0,0);
466                                 do {
467                                         c = getch();
468                                         if (c == 0) c = getch() << 8;
469                                 } while (!(c == 13 || c == 27));
470                                 vga_msg_box_destroy(&vgabox);
471                                 if (c == 27) continue;
472                         }
473
474                         if (!drive_rw_test_nfo.can_do_lba48 &&
475                                 (select == DRIVE_RW_MODE_LBA48 ||
476                                 select == DRIVE_RW_MODE_LBA48_MULTIPLE)) {
477
478                                 vga_msg_box_create(&vgabox,
479                                         "The IDE device doesn't seem to support 48-bit LBA.\n"
480                                         "Are you sure you want to choose this mode?\n"
481                                         "\n"
482                                         "Hit ENTER to proceed, ESC to cancel"
483                                         ,0,0);
484                                 do {
485                                         c = getch();
486                                         if (c == 0) c = getch() << 8;
487                                 } while (!(c == 13 || c == 27));
488                                 vga_msg_box_destroy(&vgabox);
489                                 if (c == 27) continue;
490                         }
491
492                         if (select >= 0)
493                                 drive_rw_test_nfo.mode = select;
494
495                         break;
496                 }
497                 else if (c == 0x4800) {
498                         if (--select < -1)
499                                 select = mbox.item_max;
500
501                         redraw = 1;
502                 }
503                 else if (c == 0x5000) {
504                         if (++select > mbox.item_max)
505                                 select = -1;
506
507                         redraw = 1;
508                 }
509         }
510 }
511
512 /*-----------------------------------------------------------------*/
513
514 const char *drive_readwrite_tests_menustrings[] = {
515         "Show IDE register taskfile",           /* 0 */
516         "Reading tests >>",
517         "Writing tests >>",
518         "Read verify tests"
519 };
520
521 void do_drive_readwrite_tests(struct ide_controller *ide,unsigned char which) {
522         struct menuboxbounds mbox;
523         char backredraw=1;
524         VGA_ALPHA_PTR vga;
525         unsigned int x,y;
526         int select=-1;
527         char redraw=1;
528         int c;
529
530         /* get geometry and max sector count *NOW* then the user can tweak them later */
531         memset(&drive_rw_test_nfo,0,sizeof(drive_rw_test_nfo));
532         {
533                 uint16_t info[256];
534
535                 c = do_ide_identify((unsigned char*)info,sizeof(info),ide,which,0xEC/*ATA IDENTIFY DEVICE*/);
536                 if (c < 0) return;
537
538                 drive_rw_test_nfo.can_do_lba = (info[49] & 0x200) ? 1 : 0;
539                 drive_rw_test_nfo.can_do_multiple = ((info[47] & 0xFF) != 0) ? 1 : 0;
540                 drive_rw_test_nfo.can_do_lba48 = drive_rw_test_nfo.can_do_lba && ((info[83] & 0x400) ? 1 : 0);
541
542                 /* NTS: Never mind the thousands of OSes out there still using these fields, ATA-8 marks them "obsolete".
543                  *      Thanks. You guys realize this is the same logic behind the infuriating number of APIs in Windows
544                  *      that are "obsolete" yet everything relies on them?
545                  *
546                  *      This is why you keep OLDER copies of standards around, guys! */
547                 drive_rw_test_nfo.num_cylinder = info[54];      /* number of current logical cylinders */
548                 drive_rw_test_nfo.num_head = info[55];          /* number of current logical heads */
549                 drive_rw_test_nfo.num_sector = info[56];        /* number of current logical sectors */
550                 if (drive_rw_test_nfo.num_cylinder == 0 && drive_rw_test_nfo.num_head == 0 && drive_rw_test_nfo.num_sector == 0) {
551                         drive_rw_test_nfo.num_cylinder = info[1]; /* number of logical cylinders */
552                         drive_rw_test_nfo.num_head = info[3];   /* number of logical heads */
553                         drive_rw_test_nfo.num_sector = info[6]; /* number of logical sectors */
554                 }
555
556                 if (drive_rw_test_nfo.can_do_lba48)
557                         drive_rw_test_nfo.max_lba = ((uint64_t)info[103] << 48ULL) + ((uint64_t)info[102] << 32ULL) +
558                                 ((uint64_t)info[101] << 16ULL) + ((uint64_t)info[100]);
559                 if (drive_rw_test_nfo.max_lba == 0)
560                         drive_rw_test_nfo.max_lba = ((uint64_t)info[61] << 16ULL) + ((uint64_t)info[60]);
561                 if (drive_rw_test_nfo.max_lba == 0)
562                         drive_rw_test_nfo.max_lba = ((uint64_t)info[58] << 16ULL) + ((uint64_t)info[57]);
563
564                 drive_rw_test_nfo.sector = 1;
565                 drive_rw_test_nfo.read_sectors = 1;
566                 drive_rw_test_nfo.mode = DRIVE_RW_MODE_CHS;
567                 if (drive_rw_test_nfo.can_do_multiple && (info[59]&0x100))
568                         drive_rw_test_nfo.multiple_sectors = info[59]&0xFF;
569                 if (drive_rw_test_nfo.can_do_multiple && (info[47]&0xFF) != 0)
570                         drive_rw_test_nfo.max_multiple_sectors = info[47]&0xFF;
571         }
572
573         /* UI element vars */
574         menuboxbounds_set_def_list(&mbox,/*ofsx=*/4,/*ofsy=*/7,/*cols=*/1);
575         menuboxbounds_set_item_strings_arraylen(&mbox,drive_readwrite_tests_menustrings);
576
577         while (1) {
578                 if (backredraw) {
579                         vga = vga_alpha_ram;
580                         backredraw = 0;
581                         redraw = 1;
582
583                         for (y=0;y < vga_height;y++) {
584                                 for (x=0;x < vga_width;x++) {
585                                         *vga++ = 0x1E00 + 177;
586                                 }
587                         }
588
589                         vga_moveto(0,0);
590
591                         vga_write_color(0x1F);
592                         vga_write("        IDE controller read/write tests ");
593                         sprintf(tmp,"@%X",ide->base_io);
594                         vga_write(tmp);
595                         if (ide->alt_io != 0) {
596                                 sprintf(tmp," alt %X",ide->alt_io);
597                                 vga_write(tmp);
598                         }
599                         if (ide->irq >= 0) {
600                                 sprintf(tmp," IRQ %d",ide->irq);
601                                 vga_write(tmp);
602                         }
603                         vga_write(which ? " Slave" : " Master");
604                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
605
606                         vga_write_color(0xC);
607                         vga_write("WARNING: This code talks directly to your hard disk controller.");
608                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
609                         vga_write_color(0xC);
610                         vga_write("         If you value the data on your hard drive do not run this program.");
611                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
612                 }
613
614                 if (redraw) {
615                         redraw = 0;
616
617                         vga_moveto(mbox.ofsx,mbox.ofsy - 2);
618                         vga_write_color((select == -1) ? 0x70 : 0x0F);
619                         vga_write("Back to IDE controller main menu");
620                         while (vga_pos_x < (mbox.width+mbox.ofsx) && vga_pos_x != 0) vga_writec(' ');
621
622                         menuboxbound_redraw(&mbox,select);
623                 }
624
625                 c = getch();
626                 if (c == 0) c = getch() << 8;
627
628                 if (c == 27) {
629                         break;
630                 }
631                 else if (c == 13) {
632                         if (select == -1)
633                                 break;
634
635                         switch (select) {
636                                 case 0: /* show IDE register taskfile */
637                                         do_common_show_ide_taskfile(ide,which);
638                                         redraw = backredraw = 1;
639                                         break;
640                                 case 1: /* Read tests */
641                                         do_drive_read_test(ide,which);
642                                         redraw = backredraw = 1;
643                                         break;
644                                 case 2: /* Write tests */
645                                         do_drive_write_test(ide,which);
646                                         redraw = backredraw = 1;
647                                         break;
648                                 case 3: /* Read verify tests */
649 #ifdef READ_VERIFY
650                                         do_drive_read_verify_test(ide,which);
651                                         redraw = backredraw = 1;
652 #endif
653                                         break;
654                         };
655                 }
656                 else if (c == 0x4800) {
657                         if (--select < -1)
658                                 select = mbox.item_max;
659
660                         redraw = 1;
661                 }
662                 else if (c == 0x4B00) { /* left */
663                         redraw = 1;
664                 }
665                 else if (c == 0x4D00) { /* right */
666                         redraw = 1;
667                 }
668                 else if (c == 0x5000) {
669                         if (++select > mbox.item_max)
670                                 select = -1;
671
672                         redraw = 1;
673                 }
674         }
675 }
676