]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/sndsb/pnpcfg.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / sndsb / pnpcfg.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/dos/dos.h>
14 #include <hw/8237/8237.h>               /* 8237 DMA */
15 #include <hw/8254/8254.h>               /* 8254 timer */
16 #include <hw/8259/8259.h>               /* 8259 PIC interrupts */
17 #include <hw/sndsb/sndsb.h>
18 #include <hw/isapnp/isapnp.h>
19 #include <hw/sndsb/sndsbpnp.h>
20
21 /* NTS: caller is expected to WAKE[CSN] the card for us */
22 void ms_virtualpc_prompt() {
23         int dma,irq=0;
24
25         printf("Currently configured:\n");
26
27         isa_pnp_write_address(0x07);    /* log device select */
28         isa_pnp_write_data(0x00);       /* main device */
29
30         /* NTS: I/O port is reported "fixed" in both PnP BIOS and configuration data */
31         dma = isa_pnp_read_dma(0);      /* FIXME: Does Virtual PC support changing this value? */
32         irq = isa_pnp_read_irq(0);      /* FIXME: Does Virtual PC support changing this value? */
33
34         printf("     DMA (main)            %d\n",dma);
35         printf("     IRQ                   %d\n",irq);
36
37         while (getch() != 13);
38 }
39
40 enum {
41     SB_VIBRA=0,
42     SB_AWE
43 };
44
45 /* NTS: caller is expected to WAKE[CSN] the card for us */
46 /* TODO: On AWE32/AWE64 cards the wavetable section is logical device #2 */
47 void ct_sb16pnp_prompt(int typ) {
48         int io[3]={0,0,0},dma[2]={0,0},irq=0,val,game,wavetable;
49
50         printf("Answer the questions. You may enter -1 to skip card, -2 to unassign\n");
51         printf("or -3 to not change.\n");
52         printf("Currently configured:\n");
53
54         isa_pnp_write_address(0x07);    /* log device select */
55         isa_pnp_write_data(0x00);       /* sound blaster (0) */
56
57         io[0] = isa_pnp_read_io_resource(0);
58         io[1] = isa_pnp_read_io_resource(1);
59         io[2] = isa_pnp_read_io_resource(2);
60         dma[0] = isa_pnp_read_dma(0);
61         dma[1] = isa_pnp_read_dma(1);
62         irq = isa_pnp_read_irq(0);
63
64         isa_pnp_write_address(0x07);    /* log device select */
65         isa_pnp_write_data(0x01);       /* gameport (1) */
66
67         game = isa_pnp_read_io_resource(0);
68
69         if (typ == SB_AWE) {
70                 isa_pnp_write_address(0x07);    /* log device select */
71                 isa_pnp_write_data(0x02);       /* wavetable (AWE) (2) */
72
73                 wavetable = isa_pnp_read_io_resource(0);
74         }
75
76         isa_pnp_write_address(0x07);    /* log device select */
77         isa_pnp_write_data(0x00);       /* main device */
78
79         printf("     I/O (SoundBlaster)    0x%03x\n",io[0]);
80         printf("     I/O (MPU)             0x%03x\n",io[1]);
81         printf("     I/O (OPL3)            0x%03x\n",io[2]);
82         printf("     I/O (GAME)            0x%03x\n",game);
83         if (typ == SB_AWE) printf("     I/O (AWE)             0x%03x\n",wavetable);
84         printf("     DMA (8-bit)           %d\n",dma[0]);
85         printf("     DMA (16-bit)          %d\n",dma[1]);
86         printf("     IRQ                   %d\n",irq);
87
88         /* 0x220,0x240,0x260,0x280 */
89         printf(" - SoundBlaster Port? (2x0 x=2,4,6,8)        :"); fflush(stdout); val=2; scanf("%d",&val);
90         if (val >= 2 && (val&1) == 0) io[0] = 0x200 + (val * 0x10);
91         else if (val == -1) return;
92         else if (val == -2) io[0] = 0;
93
94         printf(" - MPU Port? (3x0 x=0,3)                     :"); fflush(stdout); val=0; scanf("%d",&val);
95         if (val == 0 || val == 3) io[1] = 0x300 + (val * 0x10);
96         else if (val == -1) return;
97         else if (val == -2) io[1] = 0;
98
99         printf(" - OPL3 Port? (0=388 or 1=392)               :"); fflush(stdout); val=0; scanf("%d",&val);
100         if (val >= 0 && val <= 15) io[2] = 0x388 + (val * 0x4);
101         else if (val == -1) return;
102         else if (val == -2) io[2] = 0;
103
104         printf(" - GAME Port? (2x0 0-7)                      :"); fflush(stdout); val=0; scanf("%d",&val);
105         if (val >= 0 && val <= 7) game = 0x200 + val;
106         else if (val == -1) return;
107         else if (val == -2) game = 0;
108
109         if (typ == SB_AWE) {
110                 /* despite Creative's PNP configuration data, programming
111                    experience says we can literally place it anywhere in
112                    the 6xx range! */
113                 printf(" - AWE Port? (6x0 x=0,2,4,6,8)                 :"); fflush(stdout); val=0; scanf("%d",&val);
114                 if (val >= 0 && val <= 9) wavetable = 0x600 + (val * 0x10);
115                 else if (val == -1) return;
116                 else if (val == -2) wavetable = 0;
117         }
118
119         printf(" - IRQ? (5,7,9,10)                           :"); fflush(stdout); val=0; scanf("%d",&val);
120         if (val >= 2 && val <= 15) irq = val;
121         else if (val == -1) return;
122         else if (val == -2) irq = -1;
123
124         printf(" - 8-bit DMA? (0,1,3)                        :"); fflush(stdout); val=0; scanf("%d",&val);
125         if (val >= 0 && val <= 3) dma[0] = val;
126         else if (val == -1) return;
127         else if (val == -2) dma[0] = -1;
128
129         printf(" - 16-bit DMA? (0,1,3,5,6,7)                 :"); fflush(stdout); val=0; scanf("%d",&val);
130         if (val >= 0 && val <= 7) dma[1] = val;
131         else if (val == -1) return;
132         else if (val == -2) dma[1] = -1;
133
134         /* disable the device IO (0) */
135         isa_pnp_write_address(0x07);    /* log device select */
136         isa_pnp_write_data(0x00);       /* main device */
137
138         isa_pnp_write_data_register(0x30,0x00); /* activate: bit 0 */
139         isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
140
141         isa_pnp_write_io_resource(0,io[0]);
142         isa_pnp_write_io_resource(1,io[1]);
143         isa_pnp_write_io_resource(2,io[2]);
144         isa_pnp_write_dma(0,dma[0]);
145         isa_pnp_write_dma(1,dma[1]);
146         isa_pnp_write_irq(0,irq);
147         isa_pnp_write_irq_mode(0,2);    /* edge level high */
148
149         /* enable the device IO */
150         isa_pnp_write_data_register(0x30,0x01); /* activate: bit 0 */
151         isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
152
153         /* disable the device IO (1) */
154         isa_pnp_write_address(0x07);    /* log device select */
155         isa_pnp_write_data(0x01);       /* main device */
156
157         isa_pnp_write_data_register(0x30,0x00); /* activate: bit 0 */
158         isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
159
160         isa_pnp_write_io_resource(0,game);
161
162         /* enable the device IO */
163         isa_pnp_write_data_register(0x30,0x01); /* activate: bit 0 */
164         isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
165
166         if (typ == SB_AWE) {
167                 /* disable the device IO (2) */
168                 isa_pnp_write_address(0x07);    /* log device select */
169                 isa_pnp_write_data(0x02);       /* main device */
170
171                 isa_pnp_write_data_register(0x30,0x00); /* activate: bit 0 */
172                 isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
173
174                 isa_pnp_write_io_resource(0,wavetable);
175
176                 /* enable the device IO */
177                 isa_pnp_write_data_register(0x30,0x01); /* activate: bit 0 */
178                 isa_pnp_write_data_register(0x31,0x00); /* IO range check: bit 0 */
179         }
180
181         /* return back to "wait for key" state */
182         isa_pnp_write_data_register(0x02,0x02); /* bit 1: set -> return to Wait For Key state (or else a Pentium Pro system I own eventually locks up and hangs) */
183
184         printf("Okay, I reconfigured the card\n");
185         while (getch() != 13);
186 }
187
188 int main() {
189         printf("Sound Blaster Plug & Play configuration utility\n");
190
191         if (!probe_8237()) {
192                 printf("Cannot init 8237 DMA\n");
193                 return 1;
194         }
195         if (!probe_8259()) {
196                 printf("Cannot init 8259 PIC\n");
197                 return 1;
198         }
199         if (!probe_8254()) {
200                 printf("Cannot init 8254 timer\n");
201                 return 1;
202         }
203         if (!init_sndsb()) {
204                 printf("Cannot init library\n");
205                 return 1;
206         }
207         if (!init_isa_pnp_bios()) {
208                 printf("Cannot init ISA PnP\n");
209                 return 1;
210         }
211         if (find_isa_pnp_bios()) {
212                 char tmp[192];
213                 unsigned int j;
214                 const char *whatis = NULL;
215                 unsigned char csn,data[192];
216
217                 memset(data,0,sizeof(data));
218                 if (isa_pnp_bios_get_pnp_isa_cfg(data) == 0) {
219                         struct isapnp_pnp_isa_cfg *nfo = (struct isapnp_pnp_isa_cfg*)data;
220                         isapnp_probe_next_csn = nfo->total_csn;
221                         isapnp_read_data = nfo->isa_pnp_port;
222                 }
223                 else {
224                         printf("  ISA PnP BIOS failed to return configuration info\n");
225                 }
226
227                 if (isapnp_read_data != 0) {
228                         printf("Scanning ISA PnP devices...\n");
229                         for (csn=1;csn < 255;csn++) {
230                                 isa_pnp_init_key();
231                                 isa_pnp_wake_csn(csn);
232
233                                 isa_pnp_write_address(0x06); /* CSN */
234                                 if (isa_pnp_read_data() == csn) {
235                                         /* apparently doing this lets us read back the serial and vendor ID in addition to resource data */
236                                         /* if we don't, then we only read back the resource data */
237                                         isa_pnp_init_key();
238                                         isa_pnp_wake_csn(csn);
239
240                                         for (j=0;j < 9;j++) data[j] = isa_pnp_read_config();
241
242                                         if (isa_pnp_is_sound_blaster_compatible_id(*((uint32_t*)data),&whatis)) {
243                                                 isa_pnp_product_id_to_str(tmp,*((uint32_t*)data));
244
245                                                 printf("  [%u]: %02x %02x %02x %02x %02x %02x %02x %02x %02x ",csn,
246                                                         data[0],data[1],data[2],data[3],
247                                                         data[4],data[5],data[6],data[7],
248                                                         data[8]);
249
250                                                 printf("%s %s\n",tmp,whatis);
251
252                                                 if (!memcmp(tmp,"CTL",3)) {
253                                                         if (!memcmp(tmp+3,"0070",4) || !memcmp(tmp+3,"00F0",4)) {
254                                                                 isa_pnp_init_key();
255                                                                 isa_pnp_wake_csn(csn);
256                                                                 ct_sb16pnp_prompt(SB_VIBRA);
257                                                         }
258                                                         /* NTS: The 00B2 version is the "Gold" version */
259                                                         else if (!memcmp(tmp+3,"00C3",4) || !memcmp(tmp+3,"00B2",4)) {
260                                                                 isa_pnp_init_key();
261                                                                 isa_pnp_wake_csn(csn);
262                                                                 ct_sb16pnp_prompt(SB_AWE);
263                                                         }
264                                                 }
265                                                 else if (!memcmp(tmp,"TBA03B0",7)) {
266                                                         isa_pnp_init_key();
267                                                         isa_pnp_wake_csn(csn);
268                                                         ms_virtualpc_prompt();
269                                                 }
270                                         }
271                                 }
272                         }
273                 }
274         }
275         else {
276                 printf("Warning, ISA PnP BIOS not found\n");
277         }
278
279         return 0;
280 }
281