]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/ide/testrdtv.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / ide / testrdtv.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 "test.h"
37
38 #include "testnop.h"
39 #include "testpwr.h"
40
41 #ifdef READ_VERIFY
42 static const char *drive_read_verify_test_menustrings[] = {
43         "Show IDE register taskfile",           /* 0 */
44         "*mode*",                               /* 1 */ /* rewritten (CHS, LBA, CHS MULTI, etc) */
45         drive_readwrite_test_geo,
46         drive_readwrite_test_chs,
47         drive_readwrite_test_numsec,
48         "Read verify sectors",
49         "Read verify sectors continuously"
50 };
51
52 static void do_hdd_drive_read_verify_test(struct ide_controller *ide,unsigned char which,unsigned char continuous,struct drive_rw_test_info *nfo) {
53         unsigned char user_esc = 0;
54         struct ide_taskfile *tsk;
55         unsigned long tlen_sect;
56         unsigned int cleared=0;
57         int c;
58
59         if (nfo->read_sectors == 0) return;
60         if (nfo->multiple_sectors == 0) return;
61
62         idelib_controller_reset_irq_counter(ide); /* IRQ will fire after command completion */
63         tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
64
65 again:  /* jump point: send execution back here for another sector */
66         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
67                 return;
68         idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
69
70         tlen_sect = nfo->read_sectors;
71         /* C/H/S continuous: limit reads to within track, don't cross. we can't assume the drive will do that. */
72         if (continuous && (nfo->mode == DRIVE_RW_MODE_CHS || nfo->mode == DRIVE_RW_MODE_CHSMULTIPLE)) {
73                 if ((nfo->sector + tlen_sect) > nfo->num_sector)
74                         tlen_sect = (nfo->num_sector + 1 - nfo->sector);
75         }
76
77         if (nfo->mode == DRIVE_RW_MODE_LBA48 || nfo->mode == DRIVE_RW_MODE_LBA48_MULTIPLE) {
78                 tsk->sector_count = tlen_sect;
79                 tsk->lba0_3 = nfo->lba & 0xFF;
80                 tsk->lba1_4 = (nfo->lba >> 8) & 0xFF;
81                 tsk->lba2_5 = (nfo->lba >> 16) & 0xFF;
82                 tsk->lba0_3 |= ((nfo->lba >> 24) & 0xFF) << 8;
83                 tsk->lba1_4 |= ((nfo->lba >> 32) & 0xFF) << 8;
84                 tsk->lba2_5 |= ((nfo->lba >> 40) & 0xFF) << 8;
85                 tsk->head_select = (which << 4) | 0x40;
86
87                 tsk->command = 0x42; /* READ VERIFY EXT */
88                 if (idelib_controller_apply_taskfile(ide,0xFC/*base_io+2-7*/,IDELIB_TASKFILE_LBA48_UPDATE|IDELIB_TASKFILE_LBA48/*set LBA48*/) < 0)
89                         return;
90         }
91         else {
92                 if (tsk->sector_count > 256) return;
93                 tsk->sector_count = (tlen_sect&0xFF);
94                 if (nfo->mode == DRIVE_RW_MODE_CHS || nfo->mode == DRIVE_RW_MODE_CHSMULTIPLE) {
95                         tsk->chs_sector = nfo->sector;
96                         tsk->chs_cylinder_low = nfo->cylinder & 0xFF;
97                         tsk->chs_cylinder_high = (nfo->cylinder >> 8) & 0xFF;
98                         tsk->head_select = (nfo->head & 0xF) | (which << 4) | 0xA0;
99                 }
100                 else if (nfo->mode == DRIVE_RW_MODE_LBA || nfo->mode == DRIVE_RW_MODE_LBAMULTIPLE) {
101                         tsk->lba0_3 = nfo->lba & 0xFF;
102                         tsk->lba1_4 = (nfo->lba >> 8) & 0xFF;
103                         tsk->lba2_5 = (nfo->lba >> 16) & 0xFF;
104                         tsk->head_select = ((nfo->lba >> 24) & 0xF) | (which << 4) | 0xE0;
105                 }
106
107                 tsk->command = 0x40; /* READ VERIFY */
108                 if (idelib_controller_apply_taskfile(ide,0xFC/*base_io+2-7*/,IDELIB_TASKFILE_LBA48_UPDATE/*clear LBA48*/) < 0)
109                         return;
110         }
111
112         if (ide->flags.io_irq_enable) { /* NOW we wait for the IRQ */
113                 if (do_ide_controller_user_wait_irq(ide,1) < 0)
114                         return;
115                 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
116         }
117
118         if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
119                 return;
120
121         /* ---- draw contents on the screen ---- */
122         vga_write_color(0x0E);
123         if (!cleared) {
124                 vga_clear();
125                 cleared = 1;
126         }
127
128         vga_moveto(0,0);
129         vga_write("Sector verification:\n");
130         if (nfo->mode == DRIVE_RW_MODE_CHS || nfo->mode == DRIVE_RW_MODE_CHSMULTIPLE) {
131                 sprintf(tmp,"CHS %u/%u/%u    ",nfo->cylinder,nfo->head,nfo->sector); vga_write(tmp);
132         }
133         else {
134                 sprintf(tmp,"%llu-%llu",nfo->lba,nfo->lba+(unsigned long long)tlen_sect-1ULL); vga_write(tmp);
135         }
136
137         if (!idelib_controller_is_error(ide)) { /* OK. success. now read the data */
138                 vga_write_color(0x0A);
139                 vga_write(" PASSED\n");
140         }
141         else {
142                 vga_write_color(0x0C);
143                 vga_write(" FAILED\n");
144         }
145
146         if (continuous && !user_esc) {
147                 if (kbhit()) {
148                         c = getch();
149                         if (c == 0) c = getch() << 8;
150                 }
151                 else {
152                         c = 0;
153                 }
154         }
155         else {
156                 if ((c=wait_for_enter_or_escape()) == 27)
157                         return; /* allow user to exit early by hitting ESC */
158         }
159
160         if (c != 27 && !user_esc) {
161                 /* if the user hit ENTER, then read another sector and display that too */
162                 if (nfo->mode == DRIVE_RW_MODE_CHS || nfo->mode == DRIVE_RW_MODE_CHSMULTIPLE) {
163                         nfo->sector += (unsigned long long)tlen_sect;
164                         while (nfo->sector > nfo->num_sector) {
165                                 nfo->sector -= nfo->num_sector;
166                                 nfo->head++;
167                         }
168                         while (nfo->head >= nfo->num_head) {
169                                 nfo->head -= nfo->num_head;
170                                 nfo->cylinder++;
171                         }
172
173                         if (nfo->cylinder >= 16384) {
174                                 nfo->cylinder = 16383;
175                                 nfo->sector = nfo->num_sector;
176                                 nfo->head = nfo->num_head - 1;
177                         }
178
179                         nfo->lba  = (unsigned long long)nfo->cylinder * (unsigned long long)nfo->num_sector * (unsigned long long)nfo->num_head;
180                         nfo->lba += (unsigned long long)nfo->head * (unsigned long long)nfo->num_sector;
181                         nfo->lba += (unsigned long long)nfo->sector - 1ULL;
182                 }
183                 else {
184                         nfo->lba += (unsigned long long)tlen_sect;
185
186                         nfo->sector = (int)(nfo->lba % (unsigned long long)nfo->num_sector) + 1;
187                         nfo->head = (int)((nfo->lba / (unsigned long long)nfo->num_sector) % (unsigned long long)nfo->num_head);
188                         if (nfo->lba >= (16384ULL * (unsigned long long)nfo->num_sector * (unsigned long long)nfo->num_head)) {
189                                 nfo->cylinder = 16383;
190                                 nfo->sector = nfo->num_sector;
191                                 nfo->head = nfo->num_head - 1;
192                         }
193                         else {
194                                 nfo->cylinder = (int)((nfo->lba / (unsigned long long)nfo->num_sector) / (unsigned long long)nfo->num_head);
195                         }
196                 }
197
198                 goto again;
199         }
200 }
201 #endif
202
203 #ifdef READ_VERIFY
204 void do_drive_read_verify_test(struct ide_controller *ide,unsigned char which) {
205         struct menuboxbounds mbox;
206         char backredraw=1;
207         VGA_ALPHA_PTR vga;
208         unsigned int x,y;
209         int select=-1;
210         char redraw=1;
211         int c;
212
213         /* UI element vars */
214         menuboxbounds_set_def_list(&mbox,/*ofsx=*/4,/*ofsy=*/7,/*cols=*/1);
215         menuboxbounds_set_item_strings_arraylen(&mbox,drive_read_verify_test_menustrings);
216
217         while (1) {
218                 if (backredraw) {
219                         vga = vga_alpha_ram;
220                         backredraw = 0;
221                         redraw = 1;
222
223                         for (y=0;y < vga_height;y++) {
224                                 for (x=0;x < vga_width;x++) {
225                                         *vga++ = 0x1E00 + 177;
226                                 }
227                         }
228
229                         vga_moveto(0,0);
230
231                         vga_write_color(0x1F);
232                         vga_write("        IDE r/w tests ");
233                         sprintf(tmp,"@%X",ide->base_io);
234                         vga_write(tmp);
235                         if (ide->alt_io != 0) {
236                                 sprintf(tmp," alt %X",ide->alt_io);
237                                 vga_write(tmp);
238                         }
239                         if (ide->irq >= 0) {
240                                 sprintf(tmp," IRQ %d",ide->irq);
241                                 vga_write(tmp);
242                         }
243                         vga_write(which ? " Slave" : " Master");
244
245                         sprintf(tmp," lba=%u lba48=%u multiple=%u",
246                                 drive_rw_test_nfo.can_do_lba?1:0,
247                                 drive_rw_test_nfo.can_do_lba48?1:0,
248                                 drive_rw_test_nfo.can_do_multiple?1:0);
249                         vga_write(tmp);
250
251                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
252
253                         vga_write_color(0xC);
254                         vga_write("WARNING: This code talks directly to your hard disk controller.");
255                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
256                         vga_write_color(0xC);
257                         vga_write("         If you value the data on your hard drive do not run this program.");
258                         while (vga_pos_x < vga_width && vga_pos_x != 0) vga_writec(' ');
259                 }
260
261                 if (redraw) {
262                         redraw = 0;
263
264                         drive_read_verify_test_menustrings[1] = drive_readwrite_test_modes[drive_rw_test_nfo.mode];
265
266                         sprintf(drive_readwrite_test_geo,"Geometry: C/H/S %u/%u/%u LBA %llu",
267                                 drive_rw_test_nfo.num_cylinder,
268                                 drive_rw_test_nfo.num_head,
269                                 drive_rw_test_nfo.num_sector,
270                                 drive_rw_test_nfo.max_lba);
271
272                         sprintf(drive_readwrite_test_chs,"Position: C/H/S %u/%u/%u LBA %llu",
273                                 drive_rw_test_nfo.cylinder,
274                                 drive_rw_test_nfo.head,
275                                 drive_rw_test_nfo.sector,
276                                 drive_rw_test_nfo.lba);
277
278                         sprintf(drive_readwrite_test_numsec,"Number of sectors per read: %u",
279                                 drive_rw_test_nfo.read_sectors);
280
281                         sprintf(drive_readwrite_test_mult,"Multiple mode: %u sectors (max=%u)",
282                                 drive_rw_test_nfo.multiple_sectors,
283                                 drive_rw_test_nfo.max_multiple_sectors);
284
285                         vga_moveto(mbox.ofsx,mbox.ofsy - 2);
286                         vga_write_color((select == -1) ? 0x70 : 0x0F);
287                         vga_write("Back to IDE controller main menu");
288                         while (vga_pos_x < (mbox.width+mbox.ofsx) && vga_pos_x != 0) vga_writec(' ');
289
290                         menuboxbound_redraw(&mbox,select);
291                 }
292
293                 c = getch();
294                 if (c == 0) c = getch() << 8;
295
296                 if (c == 27) {
297                         break;
298                 }
299                 else if (c == 13) {
300                         if (select == -1)
301                                 break;
302
303                         switch (select) {
304                                 case 0: /* show IDE register taskfile */
305                                         do_common_show_ide_taskfile(ide,which);
306                                         redraw = backredraw = 1;
307                                         break;
308                                 case 1: /* Mode */
309                                         do_drive_readwrite_test_choose_mode(ide,which,&drive_rw_test_nfo);
310                                         redraw = backredraw = 1;
311                                         break;
312                                 case 2: /* Edit geometry/max LBA */
313                                         do_drive_readwrite_edit_chslba(ide,which,&drive_rw_test_nfo,/*editgeo*/1);
314                                         redraw = 1;
315                                         break;
316                                 case 3: /* Edit position */
317                                         do_drive_readwrite_edit_chslba(ide,which,&drive_rw_test_nfo,/*editgeo*/0);
318                                         redraw = 1;
319                                         break;
320                                 case 4: /* Number of sectors */
321                                         c = prompt_sector_count();
322                                         if (c >= 1 && c <= 256) {
323                                                 drive_rw_test_nfo.read_sectors = c;
324                                                 redraw = 1;
325                                         }
326                                         break;
327                                 case 5: /*Read sectors*/
328                                 case 6: /*Read sectors continuously*/
329                                         do_hdd_drive_read_verify_test(ide,which,/*continuous=*/(select==6),&drive_rw_test_nfo);
330                                         redraw = backredraw = 1;
331                                         break;
332                         };
333                 }
334                 else if (c == 0x4800) {
335                         if (--select < -1)
336                                 select = mbox.item_max;
337
338                         redraw = 1;
339                 }
340                 else if (c == 0x4B00) { /* left */
341                         switch (select) {
342                                 case 1: /* Mode */
343                                         do {
344                                                 if (drive_rw_test_nfo.mode == 0)
345                                                         drive_rw_test_nfo.mode = DRIVE_RW_MODE_MAX-1;
346                                                 else
347                                                         drive_rw_test_nfo.mode--;
348                                         } while (!drive_rw_test_mode_supported(&drive_rw_test_nfo));
349                                         break;
350                                 case 4: /* Number of sectors */
351                                         if (drive_rw_test_nfo.read_sectors > 1)
352                                                 drive_rw_test_nfo.read_sectors--;
353                                         break;
354                         };
355
356                         redraw = 1;
357                 }
358                 else if (c == 0x4D00) { /* right */
359                         switch (select) {
360                                 case 1: /* Mode */
361                                         do {
362                                                 if (++drive_rw_test_nfo.mode >= DRIVE_RW_MODE_MAX)
363                                                         drive_rw_test_nfo.mode = 0;
364                                         } while (!drive_rw_test_mode_supported(&drive_rw_test_nfo));
365                                         break;
366                                 case 4: /* Number of sectors */
367                                         if (drive_rw_test_nfo.read_sectors < 256)
368                                                 drive_rw_test_nfo.read_sectors++;
369                                         break;
370                         };
371
372                         redraw = 1;
373                 }
374                 else if (c == 0x5000) {
375                         if (++select > mbox.item_max)
376                                 select = -1;
377
378                         redraw = 1;
379                 }
380         }
381 }
382 #endif /*READ_VERIFY*/
383