remove PMC using macros
[nouveau] / src / nv_bios.c
1 /*
2  * Copyright 2005-2006 Erik Waling
3  * Copyright 2006 Stephane Marchesin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23
24 #include "nv_include.h"
25 #include "nvreg.h"
26
27 #define DEBUGLEVEL 6
28 /*#define PERFORM_WRITE*/
29
30 /* TODO: 
31  *       * Fix indentation. Currently a mix between spaces and tabs.
32  *       * PLL algorithms.
33  */
34
35 typedef struct {
36     Bool execute;
37     Bool repeat;
38 } init_exec_t;
39
40 typedef struct {
41     unsigned char *data;
42     unsigned int  length;
43     
44     CARD16      init_tbls_offset;
45     CARD16      macro_index_offset;    
46     CARD16      macro_offset; 
47     CARD16      condition_offset;
48     CARD16      io_flag_condition_offset;
49 } bios_t;
50
51
52 typedef struct {
53         char* name;
54         unsigned char id;
55         int length;
56         int length_offset;
57         int length_multiplier;
58         Bool (*handler)(ScrnInfoPtr pScrn, bios_t *, CARD16, init_exec_t *);
59 } init_tbl_entry_t;
60
61 typedef struct {
62     unsigned char id[2];
63     unsigned short length;
64     unsigned short offset;
65 } bit_entry_t;
66
67 static void parse_init_table(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset, init_exec_t *iexec);
68
69 /* #define MACRO_SIZE              8 */
70 #define CONDITION_SIZE          12
71 #define IO_FLAG_CONDITION_SIZE  9 
72
73 void still_alive()
74 {
75         sync();
76 //      usleep(200000);
77 }
78
79 static int nv_valid_reg(CARD32 reg)
80 {
81         #define WITHIN(x,y,z) ((x>=y)&&(x<y+z))
82         if (WITHIN(reg,NV_PRAMIN_OFFSET,NV_PRAMIN_SIZE))
83                 return 1;
84         if (WITHIN(reg,NV_PCRTC0_OFFSET,NV_PCRTC0_SIZE))
85                 return 1;
86         if (WITHIN(reg,NV_PRAMDAC0_OFFSET,NV_PRAMDAC0_SIZE))
87                 return 1;
88         if (WITHIN(reg,NV_PFB_OFFSET,NV_PFB_SIZE))
89                 return 1;
90         if (WITHIN(reg,NV_PFIFO_OFFSET,NV_PFIFO_SIZE))
91                 return 1;
92         if (WITHIN(reg,NV_PGRAPH_OFFSET,NV_PGRAPH_SIZE))
93                 return 1;
94         if (WITHIN(reg,NV_PEXTDEV_OFFSET,NV_PEXTDEV_SIZE))
95                 return 1;
96         if (WITHIN(reg,NV_PTIMER_OFFSET,NV_PTIMER_SIZE))
97                 return 1;
98         if (WITHIN(reg,NV_PMC_OFFSET,NV_PMC_SIZE))
99                 return 1;
100         if (WITHIN(reg,NV_FIFO_OFFSET,NV_FIFO_SIZE))
101                 return 1;
102         if (WITHIN(reg,NV_PCIO0_OFFSET,NV_PCIO0_SIZE))
103                 return 1;
104         if (WITHIN(reg,NV_PDIO0_OFFSET,NV_PDIO0_SIZE))
105                 return 1;
106         if (WITHIN(reg,NV_PVIO_OFFSET,NV_PVIO_SIZE))
107                 return 1;
108         if (WITHIN(reg,NV_PROM_OFFSET,NV_PROM_SIZE))
109                 return 1;
110         #undef WITHIN
111         return 0;
112 }
113
114 static int nv32_rd(ScrnInfoPtr pScrn, CARD32 reg, CARD32 *data)
115 {
116         NVPtr pNv = NVPTR(pScrn);
117         *data=pNv->REGS[reg/4];
118         return 1;
119 }
120
121 static int nv32_wr(ScrnInfoPtr pScrn, CARD32 reg, CARD32 data)
122 {
123 #ifdef PERFORM_WRITE
124         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "nv32_wr reg 0x%X value 0x%X\n",reg,data);
125         still_alive();
126         if (!nv_valid_reg(reg))
127         {
128                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "========= unknown reg 0x%X ==========\n",reg);
129                 return 0;
130         }
131
132         NVPtr pNv = NVPTR(pScrn);
133         pNv->REGS[reg/4]=data;
134 #endif
135         return 1;
136 }
137
138 void nv_set_crtc_index(ScrnInfoPtr pScrn, CARD8 index)
139 {
140 #ifdef PERFORM_WRITE
141         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "nv_set_crtc_index index 0x%X\n",index);
142         still_alive();
143         NVPtr pNv = NVPTR(pScrn);
144         VGA_WR08(pNv->PCIO, 0x3D4, index);
145 #endif
146 }
147
148 CARD8 nv_rd_crtc_data(ScrnInfoPtr pScrn)
149 {
150         NVPtr pNv = NVPTR(pScrn);
151         return VGA_RD08(pNv->PCIO, 0x3D5);
152 }
153
154 void nv_wr_crtc_data(ScrnInfoPtr pScrn, CARD8 val)
155 {
156 #ifdef PERFORM_WRITE
157         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "nv_wr_crtc_data value 0x%X\n",val);
158         still_alive();
159         NVPtr pNv = NVPTR(pScrn);
160         VGA_WR08(pNv->PCIO, 0x3D5, val);
161 #endif
162 }
163
164
165 static Bool init_prog(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
166 {
167     /* INIT_PROG   opcode: 0x31
168      * 
169      * offset      (8  bit): opcode
170      * offset + 1  (32 bit): reg
171      * offset + 5  (32 bit): and mask
172      * offset + 9  (8  bit): shift right
173      * offset + 10 (8  bit): number of configurations
174      * offset + 11 (32 bit): register
175      * offset + 15 (32 bit): configuration 1
176      * ...
177      * 
178      * Starting at offset + 15 there are "number of configurations"
179      * 32 bit values. To find out which configuration value to use
180      * read "CRTC reg" on the CRTC controller with index "CRTC index"
181      * and bitwise AND this value with "and mask" and then bit shift the
182      * result "shift right" bits to the right.
183      * Assign "register" with appropriate configuration value.
184      */
185     
186     CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
187     CARD32 and = *((CARD32 *) (&bios->data[offset + 5]));
188     CARD8 shiftr = *((CARD8 *) (&bios->data[offset + 9]));
189     CARD8 nr = *((CARD8 *) (&bios->data[offset + 10]));
190     CARD32 reg2 = *((CARD32 *) (&bios->data[offset + 11]));
191     CARD8 configuration;
192     CARD32 configval, tmp;
193         
194         if (iexec->execute) {
195                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%04X\n", offset, 
196                                 reg);
197
198                 nv32_rd(pScrn, reg, &tmp);
199                 configuration = (tmp & and) >> shiftr;
200
201                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONFIGURATION TO USE: 0x%02X\n", 
202                                 offset, configuration);
203
204                 if (configuration <= nr) {
205
206
207                         configval = 
208                                 *((CARD32 *) (&bios->data[offset + 15 + configuration * 4]));
209
210                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, 
211                                         reg2, configval);
212                         
213                         if (nv32_rd(pScrn, reg2, &tmp)) {
214                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
215                                                 offset, tmp);
216                         }
217                         nv32_wr(pScrn, reg2, configval);
218                 }
219         }
220         return TRUE;
221 }
222
223 static Bool init_io_restrict_prog(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
224 {
225     /* INIT_IO_RESTRICT_PROG   opcode: 0x32
226      * 
227      * offset      (8  bit): opcode
228      * offset + 1  (16 bit): CRTC reg
229      * offset + 3  (8  bit): CRTC index
230      * offset + 4  (8  bit): and mask
231      * offset + 5  (8  bit): shift right
232      * offset + 6  (8  bit): number of configurations
233      * offset + 7  (32 bit): register
234      * offset + 11 (32 bit): configuration 1
235      * ...
236      * 
237      * Starting at offset + 11 there are "number of configurations"
238      * 32 bit values. To find out which configuration value to use
239      * read "CRTC reg" on the CRTC controller with index "CRTC index"
240      * and bitwise AND this value with "and mask" and then bit shift the
241      * result "shift right" bits to the right.
242      * Assign "register" with appropriate configuration value.
243      */
244     
245     NVPtr pNv = NVPTR(pScrn);
246     CARD16 crtcreg = *((CARD16 *) (&bios->data[offset + 1]));
247     CARD8  index = *((CARD8 *) (&bios->data[offset + 3]));
248     CARD8 and = *((CARD8 *) (&bios->data[offset + 4]));
249     CARD8 shiftr = *((CARD8 *) (&bios->data[offset + 5]));
250     CARD8 nr = *((CARD8 *) (&bios->data[offset + 6]));
251     CARD32 reg = *((CARD32 *) (&bios->data[offset + 7]));
252     CARD8 configuration;
253     CARD32 configval, tmp;
254         
255         if (iexec->execute) {
256                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC REG: 0x%04X, INDEX: 0x%02X\n", offset, 
257                                 crtcreg, index);
258
259                 VGA_WR08(pNv->PCIO,crtcreg, index);
260                 configuration = (VGA_RD08(pNv->PCIO, crtcreg + 1) & and) >> shiftr;
261
262                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONFIGURATION TO USE: 0x%02X\n", 
263                                 offset, configuration);
264
265                 if (configuration <= nr) {
266
267
268                         configval = 
269                                 *((CARD32 *) (&bios->data[offset + 11 + configuration * 4]));
270
271                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, 
272                                         reg, configval);
273                         
274                         if (nv32_rd(pScrn, reg, &tmp)) {
275                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
276                                                 offset, tmp);
277                         }
278                         nv32_wr(pScrn, reg, configval);
279                 }
280         }
281     return TRUE;
282 }
283
284 static Bool init_repeat(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
285 {
286     
287     
288     CARD8 repeats = *((CARD8 *) (&bios->data[offset + 1]));
289     CARD8 i;
290     
291     if (iexec->execute) {
292                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REPEATING FOLLOWING SEGMENT %d TIMES.\n", 
293                                 offset, repeats);
294
295                 iexec->repeat = TRUE;
296
297                 for (i = 0; i < repeats - 1; i++)
298                         parse_init_table(pScrn, bios, offset + 2, iexec);
299
300                 iexec->repeat = FALSE;
301         }
302     return TRUE;
303 }
304
305 static Bool init_end_repeat(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
306 {
307     if (iexec->repeat)
308         return FALSE;
309     
310     return TRUE;
311 }
312
313 static Bool init_copy(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
314 {
315     /* XXX: double check this... */
316     NVPtr pNv = NVPTR(pScrn);
317     CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
318     CARD8 shift = *((CARD8 *) (&bios->data[offset + 5]));
319     CARD8 and1 = *((CARD8 *) (&bios->data[offset + 6]));
320     CARD16 crtcreg = *((CARD16 *) (&bios->data[offset + 7]));
321     CARD8 index = *((CARD8 *) (&bios->data[offset + 9]));
322     CARD8 and2 = *((CARD8 *) (&bios->data[offset + 10]));
323     CARD32 data;
324     CARD8 crtcdata;
325         
326         if (iexec->execute) {
327                 if (nv32_rd(pScrn, reg, &data)) {
328                         if (shift < 0x80) 
329                                 data >>= shift;
330                         else
331                                 data <<= (0x100 - shift);
332
333                         data &= and1;
334                         VGA_WR08(pNv->PCIO,crtcreg, index);
335                         crtcdata = (VGA_RD08(pNv->PCIO, crtcreg + 1) & and2) | (CARD8) data;
336
337                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
338                                         "0x%04X: CRTC REG: 0x%04X, INDEX: 0x%04X, VALUE: 0x%02X\n"
339                                         , offset, crtcreg, index, crtcdata);
340
341                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
342                                         VGA_RD08(pNv->PCIO, crtcreg + 1));
343 #ifdef PERFORM_WRITE 
344                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "init_copy crtcreg 0x%X value 0x%X\n",crtcreg+1,crtcdata);
345                         still_alive();
346                         printf("WRITE IS PERFORMED\n");
347                         VGA_WR08(pNv->PCIO,crtcreg + 1, crtcdata);
348 #endif
349                 }
350         }
351     return TRUE;
352 }
353
354 static Bool init_not(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
355 {
356     if (iexec->execute) { 
357         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: ------ SKIPPING FOLLOWING COMMANDS  ------\n",
358                 offset);
359     } else {
360         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: ------ EXECUTING FOLLOWING COMMANDS ------\n",
361                 offset);
362     }
363
364     iexec->execute = !iexec->execute;
365     return TRUE;
366 }
367
368 static Bool init_io_flag_condition(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
369 {
370     NVPtr pNv = NVPTR(pScrn);
371     CARD8 cond = *((CARD8 *) (&bios->data[offset + 1]));
372     CARD16 crtcreg = *((CARD16 *) 
373             (&bios->data[bios->io_flag_condition_offset + 
374              cond * IO_FLAG_CONDITION_SIZE]));
375     CARD8 index = *((CARD8 *) 
376             (&bios->data[bios->io_flag_condition_offset + 
377              cond * IO_FLAG_CONDITION_SIZE + 2]));
378     CARD8 and1 = *((CARD8 *) 
379             (&bios->data[bios->io_flag_condition_offset + 
380              cond * IO_FLAG_CONDITION_SIZE + 3]));
381     CARD8 shift = *((CARD8 *) 
382             (&bios->data[bios->io_flag_condition_offset + 
383              cond * IO_FLAG_CONDITION_SIZE + 4]));
384     CARD16 offs = *((CARD16 *) 
385             (&bios->data[bios->io_flag_condition_offset + 
386              cond * IO_FLAG_CONDITION_SIZE + 5]));
387     CARD8 and2 = *((CARD8 *) 
388             (&bios->data[bios->io_flag_condition_offset + 
389              cond * IO_FLAG_CONDITION_SIZE + 7]));
390     CARD8 cmpval = *((CARD8 *) 
391             (&bios->data[bios->io_flag_condition_offset + 
392              cond * IO_FLAG_CONDITION_SIZE + 8]));
393     
394     CARD8 data;
395         
396         if (iexec->execute) {
397         
398                 VGA_WR08(pNv->PCIO,crtcreg, index);
399                 data = VGA_RD08(pNv->PCIO, crtcreg + 1);
400                 data &= and1;
401                 offs += (data >> shift);
402                 data = *((CARD8 *) (&bios->data[offs]));
403                 data &= and2;
404
405                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
406                                 "0x%04X: CHECKING IF DATA: %02X equals COND: %02X\n", offset, 
407                                 data, cmpval);
408
409                 if (data == cmpval) {
410                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
411                                         "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n", 
412                                         offset);
413                 } else {
414                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONDITION IS NOT FULFILLED.\n", offset);
415                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
416                                         "0x%04X: ------ SKIPPING FOLLOWING COMMANDS  ------\n", offset);
417                         iexec->execute = FALSE;     
418                 }
419         }
420
421     return TRUE;
422 }
423
424 static Bool init_io_restrict_pll(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
425 {
426
427     xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: [ NOT YET IMPLEMENTED ]\n", offset);
428     /* XXX: this needs to be confirmed... NOT CORRECT */
429     /*init_io_restrict_prog(bios, offset, iexec);*/
430
431     
432     CARD16 crtcreg = *((CARD16 *) (&bios->data[offset + 1]));
433     CARD8  index = *((CARD8 *) (&bios->data[offset + 3]));
434     CARD8 and = *((CARD8 *) (&bios->data[offset + 4]));
435     CARD8 shiftr = *((CARD8 *) (&bios->data[offset + 5]));
436     CARD8 nr = *((CARD8 *) (&bios->data[offset + 6]));
437     CARD32 reg = *((CARD32 *) (&bios->data[offset + 7]));
438     CARD8 configuration;
439     CARD32 configval, tmp;
440 /*    
441     xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC REG: 0x%04X, INDEX: 0x%02X\n", offset, 
442             crtcreg, index, reg);
443     
444     VGA_WR08(pNv->PCIO,crtcreg, index);
445     configuration = (VGA_RD08(pNv->PCIO, crtcreg + 1) & and) >> shiftr;
446     
447     xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONFIGURATION TO USE: 0x%02X\n", 
448             offset, configuration);
449     
450     if (configuration <= nr) {
451         
452         if (DEBUGLEVEL >= 6 && nv32_rd(pScrn, reg, &configval)) 
453             xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
454                     offset, configval);
455         
456         configval = 
457             *((CARD32 *) (&bios->data[offset + 11 + configuration * 4]));
458
459         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, 
460                 reg, configval);
461     }
462 */
463 /*
464         if (iexec->execute) {    
465                 switch (reg) {
466                         case 0x00004004:
467                                 configval = 0x01014E07;
468                                 break;
469                         case 0x00004024:
470                                 configval = 0x13030E02;
471                                 break;
472                 }
473
474                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, 
475                                 reg, configval);
476
477                 if (DEBUGLEVEL >= 6 && nv32_rd(pScrn, reg, &tmp))
478                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
479                                         offset, tmp);
480
481                 nv32_wr(pScrn, reg, configval);
482
483         }*/
484     return TRUE;
485 }
486
487 static Bool init_pll(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
488 {
489  
490     CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
491     CARD32 val = *((CARD32 *) (&bios->data[offset + 5]));
492     CARD32 configval, tmp;
493 #if 0
494         if (iexec->execute) {
495                 switch (reg) {
496                         case 0x00680508:
497                                 configval = 0x00011F05;
498                                 break;
499                 }
500
501                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, reg,
502                                 configval);
503
504
505                 if (DEBUGLEVEL >= 6 && nv32_rd(pScrn, reg, &tmp)) 
506                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
507                                         offset, tmp);
508
509                 nv32_wr(pScrn, reg, configval);
510
511                 /*xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: [ NOT YET IMPLEMENTED ]\n", offset);*/
512         }
513 #endif
514     return TRUE;
515 }
516
517 Bool init_cr_idx_adr_latch(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
518 {
519     
520     CARD8 crtcindex = *((CARD8 *) (&bios->data[offset + 1]));
521     CARD8 crtcdata = *((CARD8 *) (&bios->data[offset + 2]));
522     CARD8 initial_index = *((CARD8 *) (&bios->data[offset + 3]));
523         CARD8 entries = *((CARD8 *) (&bios->data[offset + 4]));
524     CARD8 data;
525         int i;
526         
527         if (iexec->execute) {
528                 for (i = 0; i < entries; i++) {
529                         nv_set_crtc_index(pScrn, crtcindex);
530
531                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC INDEX: %02X    DATA: %02X\n", offset,
532                                         crtcindex, initial_index + i);
533
534                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
535                                         nv_rd_crtc_data(pScrn));
536
537                         nv_wr_crtc_data(pScrn, initial_index + i);
538                         
539                         nv_set_crtc_index(pScrn, crtcdata);
540
541                         data = *((CARD8 *) (&bios->data[offset + 5 + i]));
542
543                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC INDEX: %02X    DATA: %02X\n", offset,
544                                         crtcdata, data);
545
546                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
547                                         nv_rd_crtc_data(pScrn));
548
549                         nv_wr_crtc_data(pScrn, data);
550
551                 }
552         }
553         return TRUE;
554 }
555
556
557 Bool init_cr(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
558 {
559     /* XXX: IS THIS CORRECT? check the typecast .. probably wrong */
560
561     NVPtr pNv = NVPTR(pScrn);
562     CARD8 index = *((CARD32 *) (&bios->data[offset + 1])); 
563     CARD8 and = *((CARD8 *) (&bios->data[offset + 2]));
564     CARD8 or = *((CARD8 *) (&bios->data[offset + 3]));
565     CARD8 data;
566         
567         if (iexec->execute) {
568                 nv_set_crtc_index(pScrn, index);
569                 data = (nv_rd_crtc_data(pScrn) & and) | or;
570                 /*printf("and: 0x%02x    or: 0x%02x\n", and, or);*/
571                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC INDEX: 0x%02X, VALUE: 0x%02X\n", offset, 
572                                 index, data);
573
574                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
575                                 nv_rd_crtc_data(pScrn));
576
577                 nv_wr_crtc_data(pScrn, data);
578
579         }
580     return TRUE;
581     
582 }
583
584 static Bool init_zm_cr(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
585 {
586     /* INIT_ZM_CR   opcode: 0x53
587      * 
588      * offset      (8  bit): opcode
589      * offset + 1  (8  bit): CRTC index
590      * offset + 2  (8  bit): value
591      * 
592      * Assign "value" to CRTC register with index "CRTC index".
593      */
594     
595     NVPtr pNv = NVPTR(pScrn);
596     CARD8 index = *((CARD32 *) (&bios->data[offset + 1]));
597     CARD8 value = *((CARD8 *) (&bios->data[offset + 2]));
598         
599         if (iexec->execute) {
600                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC INDEX: 0x%02X, VALUE: 0x%02X\n", offset, 
601                                 index, value);
602
603                 nv_set_crtc_index(pScrn, index);
604
605                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
606                                 nv_rd_crtc_data(pScrn));
607
608                 nv_wr_crtc_data(pScrn, value);
609         }
610     return TRUE;
611 }
612
613 static Bool init_zm_cr_group(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
614 {
615     /* INIT_ZM_CR   opcode: 0x54
616      * 
617      * offset      (8  bit): opcode
618      * offset + 1  (8  bit): number of groups (index, value)
619      * offset + 2  (8  bit): index 1
620      * offset + 3  (8  bit): value 1
621      * ...
622      * 
623      * Assign "value n" to CRTC register with index "index n".
624      */
625     
626     CARD8 nr = *((CARD8 *) (&bios->data[offset + 1]));
627     CARD8 index, value;
628     int i;
629     
630         if (iexec->execute) {
631                 for (i = 0; i < nr; i++) {
632                         index = *((CARD8 *) (&bios->data[offset + 2 + 2 * i]));
633                         value = *((CARD8 *) (&bios->data[offset + 2 + 2 * i + 1]));
634
635                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CRTC INDEX: 0x%02X, VALUE: 0x%02X\n", offset,
636                                         index, value);
637
638                         nv_set_crtc_index(pScrn, index);
639
640                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset,
641                                         nv_rd_crtc_data(pScrn));
642                         nv_wr_crtc_data(pScrn, value);
643                 }
644         }
645     return TRUE;
646 }
647
648 static Bool init_condition_time(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
649 {
650     /* My BIOS does not use this command. */
651     xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: [ NOT YET IMPLEMENTED ]\n", offset);
652
653     return FALSE;
654 }
655
656 static Bool init_zm_reg_sequence(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
657 {
658     /* INIT_ZM_REG_SEQUENCE   opcode: 0x58
659      * 
660      * offset      (8  bit): opcode
661      * offset + 1  (32 bit): register base
662      * offset + 5  (8  bit): nr
663      * offset + 6  (32 bit): value to assign "register base" + 4
664      * ...
665      * 
666      * Initialzies a sequence of "nr" registers starting at "register base".
667      */
668     
669     CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
670     CARD32 nr = *((CARD8 *) (&bios->data[offset + 5]));
671     CARD32 data;
672     CARD32 tmp;
673         int i;
674     
675         if (iexec->execute) { 
676                 for (i = 0; i < nr; i++) {
677                         data = *((CARD32 *) (&bios->data[offset + 6 + i * 4]));
678                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset,
679                                         reg + i * 4, data);
680                         
681                         if (nv32_rd(pScrn, reg + i * 4, &tmp)) { 
682                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", 
683                                                 offset, tmp);
684                         }
685
686                         nv32_wr(pScrn, reg + i * 4, data);
687
688                 }
689         }
690     return TRUE;
691 }
692
693 static Bool init_indirect_reg(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
694 {
695     /* INIT_INDIRECT_REG opcode: 0x5A
696      * 
697      * offset      (8  bit): opcode
698      * offset + 1  (32 bit): register
699      * offset + 5  (16 bit): adress offset (in bios)
700      *
701      * Lookup value at offset data in the bios and write it to reg
702      */
703         NVPtr pNv = NVPTR(pScrn);
704         CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
705         CARD32 data = *((CARD16 *) (&bios->data[offset + 5]));
706         CARD32 data2 = bios->data[data];
707
708
709         if (iexec->execute) {
710                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
711                                 "0x%04X: REG: 0x%04X, DATA AT: 0x%04X, VALUE IS: 0x%08X\n", 
712                                 offset, reg, data, data2);
713
714                 if (DEBUGLEVEL >= 6) {
715                         CARD32 tmpval;
716                         nv32_rd(pScrn, reg, &tmpval);
717                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", offset, tmpval);
718                 }
719
720                 nv32_wr(pScrn, reg, data2);
721         }
722         return TRUE;
723 }
724
725
726 static Bool init_sub_direct(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
727 {
728     /* INIT_SUB_DIRECT   opcode: 0x5B
729      * 
730      * offset      (8  bit): opcode
731      * offset + 1  (16 bit): subroutine offset (in bios)
732      *
733      * Calls a subroutine that will execute commands until INIT_DONE
734      * is found. 
735      */
736     
737     CARD16 sub_offset = *((CARD16 *) (&bios->data[offset + 1]));
738        
739         if (iexec->execute) {
740                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: EXECUTING SUB-ROUTINE AT: 0x%04X\n", 
741                                 offset, sub_offset);
742
743                 parse_init_table(pScrn, bios, sub_offset, iexec);
744
745                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: END OF SUB-ROUTINE\n", offset);
746         }
747     return TRUE;
748 }
749
750 static Bool init_copy_nv_reg(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
751 {   
752     
753         CARD32 srcreg = *((CARD32 *) (&bios->data[offset + 1]));
754     CARD8 shift = *((CARD8 *) (&bios->data[offset + 5]));
755     CARD32 and1 = *((CARD32 *) (&bios->data[offset + 6]));
756     CARD32 xor = *((CARD32 *) (&bios->data[offset + 10]));
757     CARD32 dstreg = *((CARD32 *) (&bios->data[offset + 14]));
758     CARD32 and2 = *((CARD32 *) (&bios->data[offset + 18]));
759     CARD32 srcdata;
760         CARD32 dstdata;
761         
762         if (iexec->execute) {
763                 nv32_rd(pScrn, srcreg, &srcdata);
764
765                 if (shift > 0)
766                         srcdata >>= shift;
767                 else
768                         srcdata <<= shift;
769
770                 srcdata = (srcdata & and1) ^ xor;
771
772                 nv32_rd(pScrn, dstreg, &dstdata);
773                 dstdata &= and2;
774
775                 dstdata |= srcdata;
776
777                 CARD32 tmp;             
778                 nv32_rd(pScrn, dstreg, &tmp);
779
780                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, dstreg, 
781                                 dstdata);
782
783                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", offset, tmp);
784
785                 nv32_wr(pScrn, dstreg, dstdata);
786
787         }
788         return TRUE;
789 }
790
791 static Bool init_zm_index_io(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
792 {
793     NVPtr pNv = NVPTR(pScrn);
794     CARD16 crtcreg = *((CARD16 *) (&bios->data[offset + 1]));
795     CARD8 index = *((CARD8 *) (&bios->data[offset + 3]));
796     CARD8 value = *((CARD8 *) (&bios->data[offset + 4]));
797     
798         
799         if (iexec->execute) {
800                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
801                                 "0x%04X: CRTC REG: 0x%04X, INDEX: 0x%04X, VALUE: 0x%02X\n", 
802                                 offset, crtcreg, index, value);
803
804                 VGA_WR08(pNv->PCIO,crtcreg, index);
805
806                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
807                                 VGA_RD08(pNv->PCIO, crtcreg + 1));
808         
809 #ifdef PERFORM_WRITE
810                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "init_zm_index_io crtcreg 0x%X value 0x%X\n",crtcreg+1,value);
811                 still_alive();
812                 VGA_WR08(pNv->PCIO,crtcreg + 1, value);
813 #endif
814         }
815     return TRUE;
816 }
817
818 static Bool init_compute_mem(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
819 {
820         // FIXME replace with a suitable implementation
821 #if 0
822         CARD16 ramcfg = *((CARD16 *) (&bios->data[bios->ram_table_offset]));
823     CARD32 pfb_debug;
824     CARD32 strapinfo;
825     CARD32 ramcfg2;
826     
827         if (iexec->execute) {
828                 nv32_rd(pScrn, 0x00101000, &strapinfo);
829                 nv32_rd(pScrn, 0x00100080, &pfb_debug);
830
831                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "STRAPINFO: 0x%08X\n", strapinfo);
832                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "PFB_DEBUG: 0x%08X\n", pfb_debug);
833                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "RAM CFG: 0x%04X\n", ramcfg);
834
835                 pfb_debug &= 0xffffffef;
836                 strapinfo >>= 2;
837                 strapinfo &= 0x0000000f;
838                 ramcfg2 = *((CARD16 *) 
839                                 (&bios->data[bios->ram_table_offset + (2 * strapinfo)])); 
840
841                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "AFTER MANIPULATION\n");
842                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "STRAPINFO: 0x%08X\n", strapinfo);
843                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "PFB_DEBUG: 0x%08X\n", pfb_debug);
844                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "RAM CFG2: 0x%08X\n", ramcfg2);
845
846                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: [ NOT YET IMPLEMENTED ]\n", offset);
847
848
849                 CARD32 reg1;
850                 CARD32 reg2;
851
852                 nv32_rd(pScrn, 0x00100200, &reg1);
853                 nv32_rd(pScrn, 0x0010020C, &reg2);
854
855                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x00100200: 0x%08X\n", reg1);
856                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x0010020C: 0x%08X\n", reg2);
857
858
859         }
860 #endif
861     return TRUE;
862 }
863
864 static Bool init_reset(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
865 {
866     
867     CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
868     CARD32 value1 = *((CARD32 *) (&bios->data[offset + 5]));
869     CARD32 value2 = *((CARD32 *) (&bios->data[offset + 9]));
870     
871         if (iexec->execute) {
872                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", 
873                                 offset, reg, value1);
874                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", 
875                                 offset, reg, value2);
876
877                 if (DEBUGLEVEL >= 6) {
878                         CARD32 tmpval;
879                         nv32_rd(pScrn, reg, &tmpval);
880                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", offset, tmpval);
881                         /*
882                         nv32_rd(pScrn, PCICFG(PCICFG_ROMSHADOW), &tmpval);
883                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: PCICFG_ROMSHADOW: 0x%02X\n", offset, tmpval);
884                         */
885                 }
886                 nv32_wr(pScrn, reg, value1);
887                 nv32_wr(pScrn, reg, value2);
888
889         }
890     /* PCI Config space init needs to be added here. */
891     /*
892     if (nv32_rd(pScrn, PCICFG(PCICFG_ROMSHADOW), value1))
893         nv32_wr(pScrn, PCICFG(PCICFG_ROMSHADOW), value1 & 0xfffffffe)   
894     
895     */
896     return TRUE;
897 }
898
899 static Bool init_index_io8(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
900 {
901     /* INIT_INDEX_IO8   opcode: 0x69
902      * 
903      * offset      (8  bit): opcode
904      * offset + 1  (16 bit): CRTC reg
905      * offset + 3  (8  bit): and mask
906      * offset + 4  (8  bit): or with
907      * 
908      * 
909      */
910     
911     NVPtr pNv = NVPTR(pScrn);
912     CARD16 reg = *((CARD16 *) (&bios->data[offset + 1]));
913     CARD8 and  = *((CARD8 *) (&bios->data[offset + 3]));
914     CARD8 or = *((CARD8 *) (&bios->data[offset + 4]));
915     CARD8 data;
916         
917
918         if (iexec->execute) {
919                 data = (VGA_RD08(pNv->PCIO, reg) & and) | or;
920
921                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
922                                 "0x%04X: CRTC REG: 0x%04X, VALUE: 0x%02X\n", 
923                                 offset, reg, data);
924                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
925                                 VGA_RD08(pNv->PCIO, reg));
926
927 #ifdef PERFORM_WRITE
928                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "init_index_io8 crtcreg 0x%X value 0x%X\n",reg,data);
929                 still_alive();
930                 VGA_WR08(pNv->PCIO, reg, data);
931 #endif
932                 
933         }
934         return TRUE;
935         
936 }
937
938 static Bool init_sub(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
939 {
940     CARD8 sub = *((CARD8 *) (&bios->data[offset + 1]));
941     
942     if (iexec->execute) {
943                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: EXECUTING SUB-SCRIPT: %d\n", offset, sub);
944
945                 parse_init_table(pScrn, bios, 
946                                 *((CARD16 *) (&bios->data[bios->init_tbls_offset + sub * 2])),
947                                 iexec);
948
949                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: END OF SUB-SCRIPT\n", offset);
950         }
951     return TRUE;
952 }
953
954 static Bool init_ram_condition(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
955 {
956         /* INIT_RAM_CONDITION   opcode: 0x6D
957          * 
958          * offset      (8  bit): opcode
959          * offset + 1  (8  bit): and mask
960          * offset + 2  (8  bit): cmpval
961          *
962          * Test if (NV_PFB_BOOT & and mask) matches cmpval
963          */
964         NVPtr pNv = NVPTR(pScrn);
965         CARD8 and = *((CARD8 *) (&bios->data[offset + 1]));
966         CARD8 cmpval = *((CARD8 *) (&bios->data[offset + 2]));
967         CARD32 data;
968
969         if (iexec->execute) {
970                 data=(pNv->PFB[NV_PFB_BOOT/4])&and;
971
972                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
973                                 "0x%04X: CHECKING IF REGVAL: 0x%08X equals COND: 0x%08X\n",
974                                 offset, data, cmpval);
975
976                 if (data == cmpval) {
977                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
978                                         "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n",
979                                         offset);
980                 } else {
981                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONDITION IS NOT FULFILLED.\n", offset);
982                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
983                                         "0x%04X: ------ SKIPPING FOLLOWING COMMANDS  ------\n", offset);
984                         iexec->execute = FALSE;     
985                 }
986         }
987         return TRUE;
988 }
989
990 static Bool init_nv_reg(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
991 {
992         /* INIT_NV_REG   opcode: 0x6E
993          * 
994          * offset      (8  bit): opcode
995          * offset + 1  (32 bit): register
996          * offset + 5  (32 bit): and mask
997          * offset + 9  (32 bit): or with
998          *
999          * Assign "register" to (REGVAL(register) & "and mask") | "or with";
1000          */
1001
1002         CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
1003         CARD32 and = *((CARD32 *) (&bios->data[offset + 5]));
1004         CARD32 or = *((CARD32 *) (&bios->data[offset + 9]));
1005         CARD32 data;
1006         unsigned int status;
1007
1008         if (iexec->execute) {
1009
1010                 /* end temp test */
1011                 if ((status = nv32_rd(pScrn, reg, &data))) {
1012                         data = (data & and) | or;
1013                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, 
1014                                         reg, data);
1015
1016                         if (DEBUGLEVEL >= 6 && status) {
1017                                 CARD32 tmpval;
1018                                 nv32_rd(pScrn, reg, &tmpval);
1019                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n",
1020                                                 offset, tmpval);
1021                         }
1022
1023                         nv32_wr(pScrn, reg, data);
1024                         /* Assign: reg = data */
1025                 }
1026         }
1027         return TRUE;
1028 }
1029 #if 0
1030 static Bool init_macro(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1031 {
1032         // FIXME replace with the haiku version
1033         /* XXX: Not sure this is correct... */
1034
1035         CARD8 macro = *((CARD8 *) (&bios->data[offset + 1]));
1036         CARD32 reg = 
1037                 *((CARD32 *) (&bios->data[bios->macro_offset + macro * MACRO_SIZE]));
1038         CARD32 value =
1039                 *((CARD32 *) (&bios->data[bios->macro_offset + macro * MACRO_SIZE + 4]));
1040
1041         if (iexec->execute) {
1042                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: EXECUTING MACRO: 0x%02X\n", offset, macro);
1043                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset, reg,
1044                                 value);
1045
1046                 if (DEBUGLEVEL >= 6) {
1047                         CARD32 tmpval;
1048                         nv32_rd(pScrn, reg, &tmpval);
1049                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n",
1050                                         offset, tmpval);
1051                 }
1052
1053                 nv32_wr(pScrn, reg, value);
1054
1055         }
1056         return TRUE;
1057
1058 }
1059 #endif
1060
1061 static Bool init_macro(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1062 {
1063     CARD8 index = *((CARD8 *) (&bios->data[offset + 1]));
1064     CARD32 tmp = bios->macro_index_offset + (index << 1);
1065     CARD32 offs =  *((CARD8 *) (&bios->data[tmp]))  << 3;
1066     CARD32 nr = *((CARD8 *) (&bios->data[tmp + 1]));
1067     CARD32 reg, data;
1068
1069     int i;
1070
1071     if (iexec->execute) {
1072
1073         offs += bios->macro_offset;
1074         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: WRITE %d 32-BIT REGS:\n", offset, nr);
1075
1076         for (i = 0; i < nr; i++) {
1077             reg = *((CARD32 *) (&bios->data[offs + (i << 3)]));
1078             data = *((CARD32 *) (&bios->data[offs + (i << 3) + 4]));
1079
1080             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", offset,
1081                     reg, data);
1082
1083             if (DEBUGLEVEL >= 6) {
1084                 CARD32 tmpval;
1085                 nv32_rd(pScrn, reg, &tmpval);
1086                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n",
1087                         offset, tmpval);
1088             }
1089
1090             nv32_wr(pScrn, reg, data);
1091         }
1092
1093     }
1094         
1095     return TRUE;
1096 }
1097
1098 static Bool init_done(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1099 {
1100         return TRUE;
1101 }
1102
1103 static Bool init_resume(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1104 {
1105         if (!iexec->execute) {
1106                 iexec->execute = TRUE;;
1107                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: ---- EXECUTING FOLLOWING COMMANDS ----\n",
1108                                 offset);
1109         }
1110         return TRUE;
1111 }
1112
1113 static Bool init_ram_condition2(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1114 {
1115         /* INIT_RAM_CONDITION2   opcode: 0x73
1116          * 
1117          * offset      (8  bit): opcode
1118          * offset + 1  (8  bit): and mask
1119          * offset + 2  (8  bit): cmpval
1120          *
1121          * Test if (NV_PEXTDEV_BOOT & and mask) matches cmpval
1122          */
1123         NVPtr pNv = NVPTR(pScrn);
1124         CARD32 and = *((CARD32 *) (&bios->data[offset + 1]));
1125         CARD32 cmpval = *((CARD32 *) (&bios->data[offset + 5]));
1126         CARD32 data;
1127
1128         if (iexec->execute) {
1129                 data=(pNv->PEXTDEV[NV_PEXTDEV_BOOT/4])&and;
1130
1131                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1132                                 "0x%04X: CHECKING IF REGVAL: 0x%08X equals COND: 0x%08X\n",
1133                                 offset, data, cmpval);
1134
1135                 if (data == cmpval) {
1136                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1137                                         "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n",
1138                                         offset);
1139                 } else {
1140                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONDITION IS NOT FULFILLED.\n", offset);
1141                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1142                                         "0x%04X: ------ SKIPPING FOLLOWING COMMANDS  ------\n", offset);
1143                         iexec->execute = FALSE;     
1144                 }
1145         }
1146         return TRUE;
1147 }
1148
1149 static Bool init_time(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1150 {
1151         /* INIT_TIME   opcode: 0x74
1152          * 
1153          * offset      (8  bit): opcode
1154          * offset + 1  (16 bit): time
1155          * 
1156          * Sleep for "time" microseconds.
1157          */
1158
1159         CARD16 time = *((CARD16 *) (&bios->data[offset + 1]));
1160
1161         if (iexec->execute) {
1162                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: Sleeping for 0x%04X microseconds.\n", 
1163                                 offset, time);
1164
1165                 usleep(time);
1166         }
1167         return TRUE;
1168 }
1169
1170 static Bool init_condition(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1171 {
1172         CARD8 cond = *((CARD8 *) (&bios->data[offset + 1]));
1173         CARD32 reg = 
1174                 *((CARD32 *) 
1175                                 (&bios->data[bios->condition_offset + cond * CONDITION_SIZE]));
1176         CARD32 and = 
1177                 *((CARD32 *) 
1178                                 (&bios->data[bios->condition_offset + cond * CONDITION_SIZE + 4]));
1179         CARD32 cmpval = 
1180                 *((CARD32 *) 
1181                                 (&bios->data[bios->condition_offset + cond * CONDITION_SIZE + 8]));
1182         CARD32 data;
1183
1184         if (iexec->execute) {
1185                 if (nv32_rd(pScrn, reg, &data)) {
1186                         data &= and;
1187
1188                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1189                                         "0x%04X: CHECKING IF REGVAL: 0x%08X equals COND: 0x%08X\n",
1190                                         offset, data, cmpval);
1191
1192                         if (data == cmpval) {
1193                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1194                                                 "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n",
1195                                                 offset);
1196                         } else {
1197                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CONDITION IS NOT FULFILLED.\n", offset);
1198                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1199                                                 "0x%04X: ------ SKIPPING FOLLOWING COMMANDS  ------\n", offset);
1200                                 iexec->execute = FALSE;     
1201                         }
1202
1203                 }
1204         }
1205         return TRUE;
1206 }
1207
1208 static Bool init_index_io(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1209 {
1210         /* INIT_INDEX_IO   opcode: 0x78
1211          * 
1212          * offset      (8  bit): opcode
1213          * offset + 1  (16 bit): CRTC reg
1214          * offset + 3  (8  bit): CRTC index
1215          * offset + 4  (8  bit): and mask
1216          * offset + 5  (8  bit): or with
1217          * 
1218          * 
1219          */
1220
1221         NVPtr pNv = NVPTR(pScrn);
1222         CARD16 crtcreg = *((CARD16 *) (&bios->data[offset + 1]));
1223         CARD8 index = *((CARD8 *) (&bios->data[offset + 3]));
1224         CARD8 and  = *((CARD8 *) (&bios->data[offset + 4]));
1225         CARD8 or = *((CARD8 *) (&bios->data[offset + 5]));
1226         CARD8 data;
1227
1228
1229         if (iexec->execute) {
1230                 VGA_WR08(pNv->PCIO,crtcreg, index);
1231                 /* data at reg + 1 */
1232                 data = (VGA_RD08(pNv->PCIO, crtcreg + 1) & and) | or;
1233
1234                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1235                                 "0x%04X: CRTC REG: 0x%04X, INDEX: 0x%04X, VALUE: 0x%02X\n", 
1236                                 offset, crtcreg, index, data);
1237                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%02X\n", offset, 
1238                                 VGA_RD08(pNv->PCIO, crtcreg + 1));
1239
1240 #ifdef PERFORM_WRITE
1241                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "init_index_io crtcreg 0x%X value 0x%X\n",crtcreg+1,data);
1242                 still_alive();
1243                 VGA_WR08(pNv->PCIO,crtcreg + 1, data);
1244 #endif
1245
1246         }
1247         return TRUE;
1248
1249 }
1250
1251 static Bool init_zm_reg(ScrnInfoPtr pScrn, bios_t *bios, CARD16 offset, init_exec_t *iexec)
1252 {
1253         /* INIT_ZM_REG   opcode: 0x7A
1254          * 
1255          * offset      (8  bit): opcode
1256          * offset + 1  (32 bit): register
1257          * offset + 5  (32 bit): value
1258          * 
1259          * Assign "register" to "value";
1260          */
1261
1262         CARD32 reg = *((CARD32 *) (&bios->data[offset + 1]));
1263         CARD32 value = *((CARD32 *) (&bios->data[offset + 5]));
1264
1265         if (iexec->execute) {
1266                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: REG: 0x%08X, VALUE: 0x%08X\n", 
1267                                 offset, reg, value);
1268
1269                 if (DEBUGLEVEL >= 6) {
1270                         CARD32 tmpval;
1271                         nv32_rd(pScrn, reg, &tmpval);
1272                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: CURRENT VALUE IS: 0x%08X\n", offset, tmpval);
1273                 }
1274
1275                 nv32_wr(pScrn, reg, value);
1276
1277                 /* Assign: reg = value */
1278         }
1279         return TRUE;
1280 }
1281
1282 static init_tbl_entry_t itbl_entry[] = {
1283         /* command name                       , id  , length  , offset  , mult    , command handler                 */
1284         { "INIT_PROG"                         , 0x31, 15      , 10      , 4       , init_prog                       },
1285         { "INIT_IO_RESTRICT_PROG"             , 0x32, 11      , 6       , 4       , init_io_restrict_prog           },
1286         { "INIT_REPEAT"                       , 0x33, 2       , 0       , 0       , init_repeat                     },
1287         { "INIT_END_REPEAT"                   , 0x36, 1       , 0       , 0       , init_end_repeat                 },
1288         { "INIT_COPY"                         , 0x37, 11      , 0       , 0       , init_copy                       },
1289         { "INIT_NOT"                          , 0x38, 1       , 0       , 0       , init_not                        },
1290         { "INIT_IO_FLAG_CONDITION"            , 0x39, 2       , 0       , 0       , init_io_flag_condition          },
1291 /*      [ "INIT_INDEX_ADDRESS_LATCHED"        , 0x49, x       , x       , x,      , init_idx_addr_latched           }, */       
1292         { "INIT_IO_RESTRICT_PLL"              , 0x4A, 43      , 0       , 0       , init_io_restrict_pll            },
1293         { "INIT_PLL"                          , 0x4B, 9       , 0       , 0       , init_pll                        },
1294 /*      { "INIT_I2C_BYTE"                     , 0x4C, x       , x       , x       , init_i2c_byte                   }, */
1295 /*      { "INIT_ZM_I2C_BYTE"                  , 0x4D, x       , x       , x       , init_zm_i2c_byte                }, */
1296 /*      { "INIT_ZM_I2C"                       , 0x4E, x       , x       , x       , init_zm_i2c                     }, */
1297         { "INIT_CR_INDEX_ADDRESS_LATCHED"     , 0x51, 5       , 4       , 1       , init_cr_idx_adr_latch           },
1298         { "INIT_CR"                           , 0x52, 4       , 0       , 0       , init_cr                         },
1299         { "INIT_ZM_CR"                        , 0x53, 3       , 0       , 0       , init_zm_cr                      },
1300         { "INIT_ZM_CR_GROUP"                  , 0x54, 2       , 1       , 2       , init_zm_cr_group                },
1301         { "INIT_CONDITION_TIME"               , 0x56, 3       , 0       , 0       , init_condition_time             },
1302         { "INIT_ZM_REG_SEQUENCE"              , 0x58, 6       , 5       , 4       , init_zm_reg_sequence            },
1303         { "INIT_INDIRECT_REG"                 , 0x5A, 7       , 0       , 0       , init_indirect_reg               },
1304         { "INIT_SUB_DIRECT"                   , 0x5B, 3       , 0       , 0       , init_sub_direct                 },
1305         { "INIT_COPY_NV_REG"                  , 0x5F, 22      , 0       , 0       , init_copy_nv_reg                },
1306         { "INIT_ZM_INDEX_IO"                  , 0x62, 5       , 0       , 0       , init_zm_index_io                },
1307         { "INIT_COMPUTE_MEM"                  , 0x63, 1       , 0       , 0       , init_compute_mem                },
1308         { "INIT_RESET"                        , 0x65, 13      , 0       , 0       , init_reset                      },
1309 /*      { "INIT_NEXT"                         , 0x66, x       , x       , x       , init_next                       }, */       
1310 /*      { "INIT_NEXT"                         , 0x67, x       , x       , x       , init_next                       }, */       
1311 /*      { "INIT_NEXT"                         , 0x68, x       , x       , x       , init_next                       }, */       
1312         { "INIT_INDEX_IO8"                    , 0x69, 5       , 0       , 0       , init_index_io8                  },
1313         { "INIT_SUB"                          , 0x6B, 2       , 0       , 0       , init_sub                        },
1314         { "INIT_RAM_CONDITION"                , 0x6D, 3       , 0       , 0       , init_ram_condition              },
1315         { "INIT_NV_REG"                       , 0x6E, 13      , 0       , 0       , init_nv_reg                     },
1316         { "INIT_MACRO"                        , 0x6F, 2       , 0       , 0       , init_macro                      },
1317         { "INIT_DONE"                         , 0x71, 1       , 0       , 0       , init_done                       },
1318         { "INIT_RESUME"                       , 0x72, 1       , 0       , 0       , init_resume                     },
1319         { "INIT_RAM_CONDITION2"               , 0x73, 9       , 0       , 0       , init_ram_condition2             },
1320         { "INIT_TIME"                         , 0x74, 3       , 0       , 0       , init_time                       },
1321         { "INIT_CONDITION"                    , 0x75, 2       , 0       , 0       , init_condition                  },
1322 /*      { "INIT_IO_CONDITION",                , 0x76, x       , x,      , x       , init_io_condition               }, */
1323         { "INIT_INDEX_IO"                     , 0x78, 6       , 0       , 0       , init_index_io                   },
1324 /*      { "INIT_PLL2"                         , 0x79, x       , x       , x       , init_pll2                       }, */
1325         { "INIT_ZM_REG"                       , 0x7A, 9       , 0       , 0       , init_zm_reg                     },
1326 /*      { "INIT_RAM_RESTRICT_ZM_REG_GROUP"    , 0x8F, x       , x       , x       , init_ram_restrict_zm_reg_group  }, */
1327 /*      { "INIT_COPY_ZM_REG"                  , 0x90, x       , x       , x       , init_copy_zm_reg                }, */
1328 /*      { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, x       , x       , x       , init_zm_reg_group_addr_latched  }, */
1329 /*      { "INIT_RESERVED"                     , 0x92, x       , x       , x       , init_reserved                   }, */
1330         { 0                                   , 0   , 0       , 0       , 0       , 0                               }
1331 };
1332
1333
1334 static unsigned int get_init_table_entry_length(bios_t *bios, unsigned int offset, int i)
1335 {
1336     /* Calculates the length of a given init table entry. */
1337     return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier;
1338 }
1339
1340 static void parse_init_table(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset, init_exec_t *iexec)
1341 {
1342     
1343     /* Parses all commands in a init table. */
1344     
1345     /* We start out executing all commands found in the
1346      * init table. Some op codes may change the status
1347      * of this variable to SKIP, which will cause
1348      * the following op codes to perform no operation until
1349      * the value is changed back to EXECUTE.
1350      */
1351     unsigned char id;
1352     int i;
1353     
1354     
1355     int count=0;
1356     /* Loop as long as INIT_DONE (command id 0x71) has not been found
1357      * (and offset < bios length just in case... )
1358      * (and no more than 10000 iterations just in case... ) */
1359     while (((id = bios->data[offset]) != 0x71) && (offset < bios->length) && (count++<10000)) {
1360         /* Find matching id in itbl_entry */
1361         for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
1362             ;
1363         
1364         if (itbl_entry[i].name) {
1365             
1366             xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X:  [ (0x%02X) -  %s ]\n", offset, 
1367                     itbl_entry[i].id, itbl_entry[i].name);
1368             
1369             /* execute eventual command handler */
1370             if (itbl_entry[i].handler)
1371                 if (!(*itbl_entry[i].handler)(pScrn, bios, offset, iexec))
1372                     break;
1373         
1374         } else {
1375             xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: Init table command not found: 0x%02X\n", 
1376                     offset, id);
1377         }
1378         
1379         /* Add the offset of the current command including all data
1380          * of that command. The offset will then be pointing on the
1381          * next op code.
1382          */
1383         offset += get_init_table_entry_length(bios, offset, i);
1384     }
1385 }
1386
1387 void parse_init_tables(ScrnInfoPtr pScrn, bios_t *bios) {
1388     
1389     /* Loops and calls parse_init_table() for each present table. */
1390     
1391     int i = 0;
1392     CARD16 table;
1393     init_exec_t iexec = {TRUE, FALSE};
1394     
1395     while (table = *((CARD16 *) (&bios->data[bios->init_tbls_offset + i]))) {
1396         
1397         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: Parsing init table %d\n", 
1398                 table, i / 2);
1399         
1400         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: ------ EXECUTING FOLLOWING COMMANDS ------\n",table);
1401         still_alive();
1402         parse_init_table(pScrn, bios, table, &iexec);         
1403         i += 2;
1404     }
1405 }
1406
1407 static unsigned int parse_bit_init_tbl_entry(ScrnInfoPtr pScrn, bios_t *bios, bit_entry_t *bitentry) {
1408     
1409     /* Parses the init table segment that the bit entry points to.
1410      * Starting at bitentry->offset: 
1411      * 
1412      * offset + 0  (16 bits): offset of init tables
1413      * offset + 2  (16 bits): macro index table offset
1414      * offset + 4  (16 bits): macro offset
1415      * offset + 6  (16 bits): condition offset
1416      * offset + 8  (16 bits): io flag condition offset (?)
1417      * offset + 10 (16 bits): io flag condition offset (?)
1418      * offset + 12 (16 bits): unknown
1419          *
1420      * offset + 8 and offset + 10 seems to contain the same
1421      * offsets on all bioses i have checked. Don't know which
1422      * one is the correct, therefore this code will bail out
1423      * if the two values are not the same.
1424          *
1425      * TODO:
1426      * * In addition to "conditions" and "io flag conditions" there seems to be
1427      *   "io conditions". These are probably located at offset + (8, 10 or 12).
1428      *    We need more BIOS dumps to figure this out...
1429          * 
1430          * * Are 'I' bit entries always of length 0xE?
1431          * 
1432      */
1433     
1434     if (bitentry->length < 12) {
1435         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "Unable to regocnize BIT init table entry.\n");
1436         return 0;
1437     }
1438     
1439     bios->init_tbls_offset = *((CARD16 *) (&bios->data[bitentry->offset]));
1440     bios->macro_index_offset = *((CARD16 *) (&bios->data[bitentry->offset + 2]));
1441     bios->macro_offset = *((CARD16 *) (&bios->data[bitentry->offset + 4]));
1442     bios->condition_offset = 
1443         *((CARD16 *) (&bios->data[bitentry->offset + 6]));
1444     
1445     if (*((CARD16 *) (&bios->data[bitentry->offset + 8])) != 
1446             *((CARD16 *) (&bios->data[bitentry->offset + 10]))) {
1447         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "Unable to find IO flag condition offset.\n");
1448         return 0;
1449     }
1450     
1451     bios->io_flag_condition_offset =
1452         *((CARD16 *) (&bios->data[bitentry->offset + 8]));
1453     
1454     parse_init_tables(pScrn, bios);
1455     
1456     return 1;
1457 }
1458
1459 static void parse_bit_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset) {
1460
1461         bit_entry_t *bitentry;
1462         char done = 0;
1463
1464         while (!done) {
1465                 bitentry = (bit_entry_t *) &bios->data[offset];
1466
1467                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "0x%04X: Found BIT command with id 0x%02X\n", 
1468                                 offset, bitentry->id[0]); 
1469
1470                 switch (bitentry->id[0]) {
1471                         case 0:
1472                                 /* id[0] = 0 and id[1] = 0  ==> end of BIT struture */
1473                                 if (bitentry->id[1] == 0)
1474                                         done = 1;
1475                                 break;
1476                         case 'I':
1477                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  
1478                                                 "0x%04X: Found init table entry in BIT structure.\n", 
1479                                                 offset);
1480
1481                                 parse_bit_init_tbl_entry(pScrn, bios, bitentry);
1482                                 /*parse_init_tables(pScrn, bios);*/
1483                                 break;
1484                         
1485                         /* TODO: What kind of information does the other BIT entrys point to?
1486                          *       'P' entry is probably performance tables, but there are
1487                          *       quite a few others...
1488                          */
1489                 }
1490
1491                 offset += sizeof(bit_entry_t);
1492         }
1493 }
1494
1495 static void parse_pins_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset) {
1496         int pins_version_major=bios->data[offset+5];
1497         int pins_version_minor=bios->data[offset+6];
1498         int init1 = bios->data[offset + 18] + (bios->data[offset + 19] * 256);     
1499         int init2 = bios->data[offset + 20] + (bios->data[offset + 21] * 256);     
1500         int init_size = bios->data[offset + 22] + (bios->data[offset + 23] * 256) + 1;                                                    
1501         int ram_tab;
1502
1503         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "PINS version %d.%d\n",pins_version_major,pins_version_minor);
1504
1505 #if 0
1506         if (pins_version_major==2)
1507                 ram_tab = init1-0x0010;
1508         else
1509                 ram_tab = bios->data[offset + 24] + (bios->data[offset + 25] * 256);
1510
1511         if ((pins_version_major==5)&&(pins_version_minor>=6))
1512         {
1513                 /* VCO range info */
1514                 
1515         }
1516
1517         if ((pins_version_major==5)&&(pins_version_minor>=16))
1518         {
1519                 
1520         }
1521
1522         parse_bit_init_tbl_entry(pScrn, bios, bitentry);
1523
1524 #endif
1525 }
1526
1527
1528 static unsigned int findstr(bios_t* bios, unsigned char *str, int len) {
1529     
1530     int i;
1531     
1532     for (i = 2; i < bios->length; i++)
1533         if (strncmp(&bios->data[i], str, len) == 0)
1534             return i;
1535
1536     return 0;
1537 }
1538
1539
1540 unsigned int NVParseBios(ScrnInfoPtr pScrn) {
1541
1542         unsigned int bit_offset;
1543         bios_t bios;
1544         bios.data=NULL;
1545         bios.length=NV_PROM_SIZE;
1546         unsigned char nv_signature[]={0xff,0x7f,'N','V',0x0};
1547         unsigned char bit_signature[]={'B','I','T'};
1548         NVPtr pNv;
1549         int i;
1550         pNv = NVPTR(pScrn);
1551
1552         bios.data=xalloc(NV_PROM_SIZE);
1553
1554         /* enable ROM access */
1555         nvWriteMC(pNv, 0x1850, 0x0);
1556         for(i=0;i<NV_PROM_SIZE;i++)
1557         {
1558                 /* according to nvclock, we need that to work around a 6600GT/6800LE bug */
1559                 bios.data[i]=pNv->PROM[i];
1560                 bios.data[i]=pNv->PROM[i];
1561                 bios.data[i]=pNv->PROM[i];
1562                 bios.data[i]=pNv->PROM[i];
1563                 bios.data[i]=pNv->PROM[i];
1564         }
1565         /* disable ROM access */
1566         nvWriteMC(pNv, 0x1850, 0x1);
1567
1568         /* check for BIOS signature */
1569         if (!(bios.data[0] == 0x55 && bios.data[1] == 0xAA)) {
1570                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "BIOS signature not found!\n");
1571                 xfree(bios.data);
1572                 return 0;
1573         }
1574
1575         xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "BIOS signature found.\n");
1576
1577         /* check for known signatures */
1578         if (bit_offset = findstr(&bios, bit_signature, sizeof(bit_signature))) {
1579                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "BIT signature found.\n");
1580                 parse_bit_structure(pScrn, &bios, bit_offset + 4);
1581         } else if (bit_offset = findstr(&bios, nv_signature, sizeof(nv_signature))) {
1582                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "NV signature found.\n");
1583                 parse_pins_structure(pScrn, &bios, bit_offset);
1584         } else {
1585                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,  "No known script signature found.\n");
1586         }
1587
1588         xfree(bios.data);
1589         return 1;
1590 }
1591
1592
1593