3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
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>
19 #include <hw/isapnp/isapnp.h>
20 #include <hw/parport/parpnp.h>
22 static struct info_parport *sprt = NULL;
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
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;
35 #if TARGET_MSDOS == 32
42 l1: in al,dx ; tight loop: read as FAST as you can!
55 l1: in al,dx ; tight loop: read as FAST as you can!
64 /* elapsed time? remember the timer counts downward! and wraps around within 16 bits */
65 b_tim = (b_tim - e_tim) & 0xFFFF;
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
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;
82 #if TARGET_MSDOS == 32
90 l1: in al,dx ; tight loop: read as FAST as you can!
107 l1: in al,dx ; tight loop: read as FAST as you can!
117 e_tim = read_8254(0);
119 /* elapsed time? remember the timer counts downward! and wraps around within 16 bits */
120 b_tim = (b_tim - e_tim) & 0xFFFF;
125 static unsigned int statr_test_reads[] = {512,1024,2048,4096,6000,8192,12000,16384,23000,32768,46000,65500};
128 unsigned long time_tc,time_rb; /* time passed, in tc */
129 double statr_rate,statr_time;
133 printf("PC parallel printer port test program (print)\n");
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 */
140 printf("8254 not found (I need this for time-sensitive portions of the driver)\n");
145 printf("8259 not found (I need this for portions of the test involving serial interrupts)\n");
149 if (!init_parport()) {
150 printf("Cannot init parport library\n");
154 if (init_isa_pnp_bios()) {
155 if (find_isa_pnp_bios()) {
156 printf("ISA PnP BIOS found, probing for PnP ports\n");
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] ");
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] ");
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]);
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];
190 write_8254_system_timer(0); /* make sure the timer is in rate generator mode, full counter */
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];
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
201 double et = (double)time_rb / (avgsum / avgcount);
202 if (et > (1.0 / 25)) break;
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++;
212 printf(" result >> %.1f samples/sec\n",avgsum);
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];
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
223 double et = (double)time_rb / (avgsum / avgcount);
224 if (et > (1.0 / 25)) break;
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++;
234 printf(" result >> %.1f samples/sec\n",avgsum);
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];
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
246 double et = (double)time_rb / (avgsum / avgcount);
247 if (et > (1.0 / 25)) break;
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++;
257 printf(" result >> %.1f samples/sec\n",avgsum);
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];
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
268 double et = (double)time_rb / (avgsum / avgcount);
269 if (et > (1.0 / 25)) break;
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++;
279 printf(" result >> %.1f samples/sec\n",avgsum);