]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/parport/samptest.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / parport / samptest.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 <assert.h>
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <dos.h>
11
12 #include <hw/cpu/cpu.h>
13 #include <hw/dos/dos.h>
14 #include <hw/8254/8254.h>
15 #include <hw/8259/8259.h>
16 #include <hw/dos/doswin.h>
17 #include <hw/parport/parport.h>
18
19 #include <hw/isapnp/isapnp.h>
20 #include <hw/parport/parpnp.h>
21
22 static struct info_parport *sprt = NULL;
23
24 /* NTS: Not suitable for reads that take longer than 1/18.2th of a second.
25  * this function is better suited to establishing a baseline speed from small
26  * read tests that are very likely to fall within the 18.2Hz tick rate of the
27  * system timer. also, bytecount is 16-bit on real-mode builds and cannot
28  * count beyond 64KB.
29  *
30  * WARNING: do not call with bytecount == 0! */
31 unsigned int tight_read_test(unsigned int bytecount,unsigned int io_port) {
32         unsigned int b_tim,e_tim;
33
34         b_tim = read_8254(0);
35 #if TARGET_MSDOS == 32
36         __asm {
37                 cli
38                 push            ecx
39                 push            edx
40                 mov             ecx,bytecount
41                 mov             edx,io_port
42 l1:             in              al,dx           ; tight loop: read as FAST as you can!
43                 loop            l1
44                 pop             edx
45                 pop             ecx
46                 sti
47         }
48 #else
49         __asm {
50                 cli
51                 push            cx
52                 push            dx
53                 mov             cx,bytecount
54                 mov             dx,io_port
55 l1:             in              al,dx           ; tight loop: read as FAST as you can!
56                 loop            l1
57                 pop             dx
58                 pop             cx
59                 sti
60         }
61 #endif
62         e_tim = read_8254(0);
63
64         /* elapsed time? remember the timer counts downward! and wraps around within 16 bits */
65         b_tim = (b_tim - e_tim) & 0xFFFF;
66
67         return b_tim;
68 }
69
70 /* NTS: Not suitable for reads that take longer than 1/18.2th of a second.
71  * this function is better suited to establishing a baseline speed from small
72  * read tests that are very likely to fall within the 18.2Hz tick rate of the
73  * system timer. also, bytecount is 16-bit on real-mode builds and cannot
74  * count beyond 64KB.
75  *
76  * WARNING: do not call with bytecount == 0! */
77 unsigned int tight_memstore_read_test(unsigned int bytecount,unsigned int io_port) {
78         unsigned int b_tim,e_tim;
79         unsigned char c=0xFF;
80
81         b_tim = read_8254(0);
82 #if TARGET_MSDOS == 32
83         __asm {
84                 cli
85                 push            esi
86                 push            ecx
87                 push            edx
88                 mov             ecx,bytecount
89                 mov             edx,io_port
90 l1:             in              al,dx           ; tight loop: read as FAST as you can!
91                 mov             c,al
92                 inc             esi
93                 loop            l1
94                 pop             edx
95                 pop             ecx
96                 pop             esi
97                 sti
98         }
99 #else
100         __asm {
101                 cli
102                 push            si
103                 push            cx
104                 push            dx
105                 mov             cx,bytecount
106                 mov             dx,io_port
107 l1:             in              al,dx           ; tight loop: read as FAST as you can!
108                 mov             c,al
109                 inc             si
110                 loop            l1
111                 pop             dx
112                 pop             cx
113                 pop             si
114                 sti
115         }
116 #endif
117         e_tim = read_8254(0);
118
119         /* elapsed time? remember the timer counts downward! and wraps around within 16 bits */
120         b_tim = (b_tim - e_tim) & 0xFFFF;
121
122         return b_tim;
123 }
124
125 static unsigned int statr_test_reads[] = {512,1024,2048,4096,6000,8192,12000,16384,23000,32768,46000,65500};
126
127 int main() {
128         unsigned long time_tc,time_rb; /* time passed, in tc */
129         double statr_rate,statr_time;
130         int i,avgcount=0;
131         double avgsum=0;
132
133         printf("PC parallel printer port test program (print)\n");
134
135         cpu_probe();            /* ..for the DOS probe routine */
136         probe_dos();            /* ..for the Windows detection code */
137         detect_windows();       /* Windows virtualizes the LPT ports, and we don't want probing to occur to avoid any disruption */
138
139         if (!probe_8254()) {
140                 printf("8254 not found (I need this for time-sensitive portions of the driver)\n");
141                 return 1;
142         }
143
144         if (!probe_8259()) {
145                 printf("8259 not found (I need this for portions of the test involving serial interrupts)\n");
146                 return 1;
147         }
148
149         if (!init_parport()) {
150                 printf("Cannot init parport library\n");
151                 return 1;
152         }
153
154         if (init_isa_pnp_bios()) {
155                 if (find_isa_pnp_bios()) {
156                         printf("ISA PnP BIOS found, probing for PnP ports\n");
157                         pnp_parport_scan();
158                 }
159         }
160
161         printf("Probing BIOS-listed locations ");
162         for (i=0;i < bios_parports;i++) {
163                 uint16_t port = get_bios_parport(i);
164                 printf("%03x ",port);
165                 if (probe_parport(port)) printf("[OK] ");
166                 fflush(stdout);
167         }
168         printf("\n");
169
170         printf("Probing standard port locations ");
171         for (i=0;i < STANDARD_PARPORT_PORTS;i++) {
172                 uint16_t port = standard_parport_ports[i];
173                 printf("%03x ",port);
174                 if (probe_parport(port)) printf("[OK] ");
175                 fflush(stdout);
176         }
177         printf("\n");
178
179         printf("Found parallel ports:\n");
180         for (i=0;i < info_parports;i++) {
181                 struct info_parport *prt = &info_parport[i];
182                 printf(" [%u] port=0x%04x IRQ=%d DMA=%d 10-bit=%u max-xfer-size=%u type='%s'\n",i+1,prt->port,prt->irq,prt->dma,prt->bit10,prt->max_xfer_size,parport_type_str[prt->type]);
183         }
184
185         printf("Choice? "); fflush(stdout);
186         i = 1; scanf("%d",&i); i--;
187         if (i < 0 || i >= info_parports) return 1;
188         sprt = &info_parport[i];
189
190         write_8254_system_timer(0); /* make sure the timer is in rate generator mode, full counter */
191
192         avgsum = 0; avgcount = 0;
193         printf("Timing test: tight loop (no memory store) reading status port:\n");
194         for (i=0;i < (int)(sizeof(statr_test_reads)/sizeof(statr_test_reads[0]));i++) {
195                 time_rb = statr_test_reads[i];
196                 if (i != 0) {
197                         /* compute how long this iteration will take. if we estimate the test
198                          * will take longer than 1/25 seconds, stop now. if the test takes
199                          * longer than the full countdown interval of the 8254 we cannot time
200                          * it properly. */
201                         double et = (double)time_rb / (avgsum / avgcount);
202                         if (et > (1.0 / 25)) break;
203                 }
204
205                 time_tc = tight_read_test(time_rb,sprt->port+PARPORT_IO_STATUS);
206                 statr_time = ((double)time_tc * 1000) / T8254_REF_CLOCK_HZ;
207                 statr_rate = ((double)1000 * time_rb) / statr_time;
208                 printf("   ... %lu bytes: %.6f ms (%.1f samp/sec)\n",time_rb,statr_time,statr_rate);
209                 avgsum += statr_rate; avgcount++;
210         }
211         avgsum /= avgcount;
212         printf("   result >> %.1f samples/sec\n",avgsum);
213
214         avgsum = 0; avgcount = 0;
215         printf("Timing test: tight loop (no memory store) reading data port:\n");
216         for (i=0;i < (int)(sizeof(statr_test_reads)/sizeof(statr_test_reads[0]));i++) {
217                 time_rb = statr_test_reads[i];
218                 if (i != 0) {
219                         /* compute how long this iteration will take. if we estimate the test
220                          * will take longer than 1/25 seconds, stop now. if the test takes
221                          * longer than the full countdown interval of the 8254 we cannot time
222                          * it properly. */
223                         double et = (double)time_rb / (avgsum / avgcount);
224                         if (et > (1.0 / 25)) break;
225                 }
226
227                 time_tc = tight_read_test(time_rb,sprt->port+PARPORT_IO_DATA);
228                 statr_time = ((double)time_tc * 1000) / T8254_REF_CLOCK_HZ;
229                 statr_rate = ((double)1000 * time_rb) / statr_time;
230                 printf("   ... %lu bytes: %.6f ms (%.1f samp/sec)\n",time_rb,statr_time,statr_rate);
231                 avgsum += statr_rate; avgcount++;
232         }
233         avgsum /= avgcount;
234         printf("   result >> %.1f samples/sec\n",avgsum);
235
236
237         avgsum = 0; avgcount = 0;
238         printf("Timing test: tight loop with memory store reading status port:\n");
239         for (i=0;i < (int)(sizeof(statr_test_reads)/sizeof(statr_test_reads[0]));i++) {
240                 time_rb = statr_test_reads[i];
241                 if (i != 0) {
242                         /* compute how long this iteration will take. if we estimate the test
243                          * will take longer than 1/25 seconds, stop now. if the test takes
244                          * longer than the full countdown interval of the 8254 we cannot time
245                          * it properly. */
246                         double et = (double)time_rb / (avgsum / avgcount);
247                         if (et > (1.0 / 25)) break;
248                 }
249
250                 time_tc = tight_memstore_read_test(time_rb,sprt->port+PARPORT_IO_STATUS);
251                 statr_time = ((double)time_tc * 1000) / T8254_REF_CLOCK_HZ;
252                 statr_rate = ((double)1000 * time_rb) / statr_time;
253                 printf("   ... %lu bytes: %.6f ms (%.1f samp/sec)\n",time_rb,statr_time,statr_rate);
254                 avgsum += statr_rate; avgcount++;
255         }
256         avgsum /= avgcount;
257         printf("   result >> %.1f samples/sec\n",avgsum);
258
259         avgsum = 0; avgcount = 0;
260         printf("Timing test: tight loop with memory store reading data port:\n");
261         for (i=0;i < (int)(sizeof(statr_test_reads)/sizeof(statr_test_reads[0]));i++) {
262                 time_rb = statr_test_reads[i];
263                 if (i != 0) {
264                         /* compute how long this iteration will take. if we estimate the test
265                          * will take longer than 1/25 seconds, stop now. if the test takes
266                          * longer than the full countdown interval of the 8254 we cannot time
267                          * it properly. */
268                         double et = (double)time_rb / (avgsum / avgcount);
269                         if (et > (1.0 / 25)) break;
270                 }
271
272                 time_tc = tight_memstore_read_test(time_rb,sprt->port+PARPORT_IO_DATA);
273                 statr_time = ((double)time_tc * 1000) / T8254_REF_CLOCK_HZ;
274                 statr_rate = ((double)1000 * time_rb) / statr_time;
275                 printf("   ... %lu bytes: %.6f ms (%.1f samp/sec)\n",time_rb,statr_time,statr_rate);
276                 avgsum += statr_rate; avgcount++;
277         }
278         avgsum /= avgcount;
279         printf("   result >> %.1f samples/sec\n",avgsum);
280
281         return 0;
282 }
283