]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/ide/testbusy.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / ide / testbusy.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 "test.h"
26
27 /* returns: -1 if user said to cancel
28  *          0 if not busy
29  *          1 if still busy, but user said to proceed */
30 int do_ide_controller_user_wait_busy_timeout_controller(struct ide_controller *ide,unsigned int timeout) {
31         int ret = 0;
32         
33         if (ide == NULL)
34                 return -1;
35
36         /* use the alt status register if possible, else the base I/O.
37          * the alt status register is said not to clear pending interrupts */
38         idelib_controller_update_status(ide);
39         if (idelib_controller_is_busy(ide)) {
40                 unsigned long show_countdown = (unsigned long)timeout * 10UL; /* ms -> 100us units */
41
42                 do {
43                         idelib_controller_update_status(ide);
44                         if (!idelib_controller_is_busy(ide)) break;
45
46                         /* if the drive&controller is busy then show the dialog and wait for non-busy
47                          * or until the user forces us to proceed */
48                         if (show_countdown > 0UL) {
49                                 if (--show_countdown == 0UL) {
50                                         ret = 1;
51                                         break;
52                                 }
53                         }
54
55                         t8254_wait(t8254_us2ticks(100)); /* wait 100us (0.0001 seconds) */
56                 } while (1);
57         }
58
59         return ret;
60 }
61
62 /* returns: -1 if user said to cancel
63  *          0 if not busy
64  *          1 if still busy, but user said to proceed */
65 int do_ide_controller_user_wait_busy_controller(struct ide_controller *ide) {
66         struct vga_msg_box vgabox;
67         int ret = 0,c = 0;
68         
69         if (ide == NULL)
70                 return -1;
71
72         /* use the alt status register if possible, else the base I/O.
73          * the alt status register is said not to clear pending interrupts */
74         idelib_controller_update_status(ide);
75         if (idelib_controller_is_busy(ide)) {
76                 unsigned long show_countdown = 500000UL / 100UL; /* 0.5s / 100us units */
77                 /* if the drive&controller is busy then show the dialog and wait for non-busy
78                  * or until the user forces us to proceed */
79
80                 do {
81                         idelib_controller_update_status(ide);
82                         if (!idelib_controller_is_busy(ide)) break;
83
84                         /* if the drive&controller is busy then show the dialog and wait for non-busy
85                          * or until the user forces us to proceed */
86                         if (show_countdown > 0UL) {
87                                 if (--show_countdown == 0UL)
88                                         vga_msg_box_create(&vgabox,"IDE controller busy, waiting...\n\nHit ESC to cancel, spacebar to proceed anyway",0,0);
89                         }
90
91                         if (show_countdown == 0UL && kbhit()) { /* if keyboard input and we're showing prompt */
92                                 c = getch();
93                                 if (c == 0) c = getch() << 8;
94
95                                 if (c == 27) {
96                                         ret = -1;
97                                         break;
98                                 }
99                                 else if (c == ' ') {
100                                         ret = 1;
101                                         break;
102                                 }
103                         }
104
105                         t8254_wait(t8254_us2ticks(100)); /* wait 100us (0.0001 seconds) */
106                 } while (1);
107
108                 if (show_countdown == 0UL)
109                         vga_msg_box_destroy(&vgabox);
110         }
111
112         return ret;
113 }
114
115 /* returns: -2 if an error happened
116  *          -1 if user said to cancel
117  *           0 if not busy
118  *           1 if still busy, but user said to proceed */
119 int do_ide_controller_user_wait_drive_drq(struct ide_controller *ide) {
120         struct vga_msg_box vgabox;
121         int ret = 0,c = 0;
122
123         if (ide == NULL)
124                 return -1;
125
126         /* NTS: We ignore the Drive Ready Bit, because logically, that bit reflects
127          *      when the drive is ready for another command. Obviously if we're waiting
128          *      for DATA related to a command, then the command is not complete!
129          *      I'm also assuming there are dumbshit IDE controller and hard drive
130          *      implementations dumb enough to return such confusing state. */
131         /* use the alt status register if possible, else the base I/O.
132          * the alt status register is said not to clear pending interrupts */
133         idelib_controller_update_status(ide);
134         if (!idelib_controller_is_drq_ready(ide)) {
135                 unsigned long show_countdown = 500000UL / 100UL; /* 0.5s / 100us units */
136
137                 do {
138                         idelib_controller_update_status(ide);
139                         if (idelib_controller_is_drq_ready(ide))
140                                 break;
141                         else if (idelib_controller_is_error(ide)) {
142                                 ret = -2;
143                                 break;
144                         }
145
146                         /* if the drive&controller is busy then show the dialog and wait for non-busy
147                          * or until the user forces us to proceed */
148                         if (show_countdown > 0UL) {
149                                 if (--show_countdown == 0UL)
150                                         vga_msg_box_create(&vgabox,"Waiting for Data Request from IDE device\n\nHit ESC to cancel, spacebar to proceed anyway",0,0);
151                         }
152
153                         if (show_countdown == 0UL && kbhit()) { /* if keyboard input and we're showing prompt */
154                                 c = getch();
155                                 if (c == 0) c = getch() << 8;
156
157                                 if (c == 27) {
158                                         ret = -1;
159                                         break;
160                                 }
161                                 else if (c == ' ') {
162                                         ret = 1;
163                                         break;
164                                 }
165                         }
166
167                         t8254_wait(t8254_us2ticks(100)); /* wait 100us (0.0001 seconds) */
168                 } while (1);
169
170                 if (show_countdown == 0UL)
171                         vga_msg_box_destroy(&vgabox);
172         }
173
174         return ret;
175 }
176
177 /* returns: -1 if user said to cancel
178  *          0 if not busy
179  *          1 if still busy, but user said to proceed */
180 int do_ide_controller_user_wait_irq(struct ide_controller *ide,uint16_t count) {
181         struct vga_msg_box vgabox;
182         int ret = 0,c = 0;
183
184         if (ide == NULL)
185                 return -1;
186
187         if (ide->irq_fired < count) {
188                 unsigned long show_countdown = 500000UL / 100UL; /* 0.5s / 100us units */
189
190                 do {
191                         if (ide->irq_fired >= count)
192                                 break;
193
194                         /* if the drive&controller is busy then show the dialog and wait for non-busy
195                          * or until the user forces us to proceed */
196                         if (show_countdown > 0UL) {
197                                 if (--show_countdown == 0UL)
198                                         vga_msg_box_create(&vgabox,"Waiting for IDE IRQ\n\nHit ESC to cancel, spacebar to proceed anyway",0,0);
199                         }
200
201                         if (show_countdown == 0UL && kbhit()) { /* if keyboard input and we're showing prompt */
202                                 c = getch();
203                                 if (c == 0) c = getch() << 8;
204
205                                 if (c == 27) {
206                                         ret = -1;
207                                         break;
208                                 }
209                                 else if (c == ' ') {
210                                         ret = 1;
211                                         break;
212                                 }
213                         }
214
215                         t8254_wait(t8254_us2ticks(100)); /* wait 100us (0.0001 seconds) */
216                 } while (1);
217
218                 if (show_countdown == 0UL)
219                         vga_msg_box_destroy(&vgabox);
220         }
221
222         return ret;
223 }
224
225 /* returns: -1 if user said to cancel
226  *          0 if not busy
227  *          1 if still busy, but user said to proceed */
228 int do_ide_controller_user_wait_drive_ready(struct ide_controller *ide) {
229         struct vga_msg_box vgabox;
230         int ret = 0,c;
231
232         if (ide == NULL)
233                 return -1;
234
235         /* use the alt status register if possible, else the base I/O.
236          * the alt status register is said not to clear pending interrupts */
237         idelib_controller_update_status(ide);
238         if (!idelib_controller_is_drive_ready(ide)) {
239                 unsigned long show_countdown = 500000UL / 100UL; /* 0.5s / 100us units */
240
241                 /* if the drive&controller is busy then show the dialog and wait for non-busy
242                  * or until the user forces us to proceed */
243
244                 do {
245                         idelib_controller_update_status(ide);
246                         if (idelib_controller_is_drive_ready(ide))
247                                 break;
248                         else if (idelib_controller_is_error(ide))
249                                 break; /* this is possible too?? or is VirtualBox fucking with us when the CD-ROM drive is on Primary slave? */
250
251                         if (show_countdown > 0UL) {
252                                 if (--show_countdown == 0UL)
253                                         vga_msg_box_create(&vgabox,"IDE device not ready, waiting...\n\nHit ESC to cancel, spacebar to proceed anyway",0,0);
254                         }
255
256                         if (show_countdown == 0UL && kbhit()) { /* if keyboard input and we're showing prompt */
257                                 c = getch();
258                                 if (c == 0) c = getch() << 8;
259
260                                 if (c == 27) {
261                                         ret = -1;
262                                         break;
263                                 }
264                                 else if (c == ' ') {
265                                         ret = 1;
266                                         break;
267                                 }
268                         }
269
270                         t8254_wait(t8254_us2ticks(100)); /* wait 100us (0.0001 seconds) */
271                 } while (1);
272
273                 if (show_countdown == 0UL)
274                         vga_msg_box_destroy(&vgabox);
275         }
276
277         return ret;
278 }
279