Chameleon

Chameleon Commit Details

Date:2010-03-20 12:47:42 (14 years 30 days ago)
Author:DieBuche
Commit:132
Parents: 131
Message:Adding lebidous latest changes
Changes:
D/branches/diebuche/i386/libsaio/915resolution.h
D/branches/diebuche/i386/libsaio/915resolution.c
A/branches/diebuche/i386/libsaio/gma_resolution.c
A/branches/diebuche/i386/libsaio/autoresolution.c
A/branches/diebuche/i386/libsaio/gma_resolution.h
A/branches/diebuche/i386/libsaio/nvidia_resolution.c
A/branches/diebuche/i386/libsaio/ati_resolution.c
A/branches/diebuche/i386/libsaio/autoresolution.h
A/branches/diebuche/i386/libsaio/nvidia_resolution.h
A/branches/diebuche/i386/libsaio/ati_resolution.h
M/branches/diebuche/i386/libsaio/edid.h
M/branches/diebuche/i386/libsaio/vbe.c
M/branches/diebuche/i386/libsaio/vbe.h
M/branches/diebuche/i386/boot2/gui.c
M/branches/diebuche/i386/boot2/gui.h
M/branches/diebuche/i386/libsaio/Makefile
M/branches/diebuche/i386/boot2/graphics.c
M/branches/diebuche/i386/libsaio/edid.c
M/branches/diebuche/i386/boot2/boot.c

File differences

branches/diebuche/i386/libsaio/915resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#include "libsaio.h"
#include "915resolution.h"
#include "../boot2/graphics.h"
char * chipset_type_names[] = {
"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
"946GZ", "955X", "G965", "Q965", "965GM", "975X",
"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
};
char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
int freqs[] = { 60, 75, 85 };
UInt32 get_chipset_id(void) {
outl(0xcf8, 0x80000000);
return inl(0xcfc);
}
chipset_type get_chipset(UInt32 id) {
chipset_type type;
switch (id) {
case 0x35758086:
type = CT_830;
break;
case 0x25608086:
type = CT_845G;
break;
case 0x35808086:
type = CT_855GM;
break;
case 0x25708086:
type = CT_865G;
break;
case 0x25808086:
type = CT_915G;
break;
case 0x25908086:
type = CT_915GM;
break;
case 0x27708086:
type = CT_945G;
break;
case 0x27748086:
type = CT_955X;
break;
case 0x277c8086:
type = CT_975X;
break;
case 0x27a08086:
type = CT_945GM;
break;
case 0x27ac8086:
type = CT_945GME;
break;
case 0x29708086:
type = CT_946GZ;
break;
case 0x29a08086:
type = CT_G965;
break;
case 0x29908086:
type = CT_Q965;
break;
case 0x2a008086:
type = CT_965GM;
break;
case 0x29e08086:
type = CT_X48;
break;
case 0x2a408086:
type = CT_GM45;
break;
case 0x2e108086:
case 0X2e908086:
type = CT_B43;
break;
case 0x2e208086:
type = CT_P45;
break;
case 0x2e308086:
type = CT_G41;
break;
case 0x29c08086:
type = CT_G31;
break;
case 0x29208086:
type = CT_G45;
break;
case 0x81008086:
type = CT_500;
break;
default:
type = CT_UNKWN;
break;
}
return type;
}
vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
return ptr;
}
char detect_bios_type(vbios_map * map, char modeline, int entry_size) {
UInt32 i;
UInt16 r1, r2;
r1 = r2 = 32000;
for (i=0; i < map->mode_table_size; i++) {
if (map->mode_table[i].resolution <= r1) {
r1 = map->mode_table[i].resolution;
}
else {
if (map->mode_table[i].resolution <= r2) {
r2 = map->mode_table[i].resolution;
}
}
/* printf("r1 = %d r2 = %d\n", r1, r2); */
}
return (r2-r1-6) % entry_size == 0;
}
char detect_ati_bios_type(vbios_map * map) {
return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;
}
void close_vbios(vbios_map * map);
vbios_map * open_vbios(chipset_type forced_chipset) {
UInt32 z;
vbios_map * map = NEW(vbios_map);
for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
/*
* Determine chipset
*/
if (forced_chipset == CT_UNKWN) {
map->chipset_id = get_chipset_id();
map->chipset = get_chipset(map->chipset_id);
}
else if (forced_chipset != CT_UNKWN) {
map->chipset = forced_chipset;
}
else {
map->chipset = CT_915GM;
}
/*
* Map the video bios to memory
*/
map->bios_ptr = (unsigned char *)VBIOS_START;
/*
* check if we have ATI Radeon
*/
map->ati_tables.base = map->bios_ptr;
map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") != 0) {
printf("Not an AtomBios Card\n");
} else {
map->bios = BT_ATI_1;
}
/*
* check if we have NVidia
*/
if (map->bios != BT_ATI_1) {
int i = 0;
while (i < 512) { // we don't need to look through the whole bios, just the first 512 bytes
if ((map->bios_ptr[i] == 'N')
&& (map->bios_ptr[i+1] == 'V')
&& (map->bios_ptr[i+2] == 'I')
&& (map->bios_ptr[i+3] == 'D'))
{
map->bios = BT_NVDA;
break;
}
i++;
}
}
/*
* check if we have Intel
*/
/*if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");
printf("Chipset Id: %x\n", map->chipset_id);
printf("Please report this problem to stomljen@yahoo.com\n");
close_vbios(map);
return 0;
}*/
/*
* check for others
*/
if (map->chipset == CT_UNKWN) {
printf("Unknown chipset type and unrecognized bios.\n");
printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");
printf("Chipset Id: %x\n", map->chipset_id);
close_vbios(map);
return 0;
}
/*
* Figure out where the mode table is
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))
{
unsigned char* p = map->bios_ptr + 16;
unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
while (p < limit && map->mode_table == 0) {
vbios_mode * mode_ptr = (vbios_mode *) p;
if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
map->mode_table = mode_ptr;
}
p++;
}
if (map->mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
close_vbios(map);
return 0;
}
}
else if (map->bios == BT_ATI_1)
{
map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;
unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing;
ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);
map->ati_mode_table = (char *) &std_vesa->aModeTimings;
if (map->ati_mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
close_vbios(map);
return 0;
}
map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);
if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;
}
else if (map->bios == BT_NVDA)
{
unsigned short nv_data_table_offset = 0;
unsigned short nv_modeline_2_offset = 0;
unsigned short * nv_data_table;
NV_VESA_TABLE * std_vesa;
int i = 0;
while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only
if ((map->bios_ptr[i] == 0x44)
&& (map->bios_ptr[i+1] == 0x01)
&& (map->bios_ptr[i+2] == 0x04)
&& (map->bios_ptr[i+3] == 0x00)) {
nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
break;
}
i++;
}
while (i < VBIOS_SIZE) { //We don't know how to locate it other way
if ((map->bios_ptr[i] == 0x00) && (map->bios_ptr[i+1] == 0x04) //this is the first 1024 modeline.
&& (map->bios_ptr[i+2] == 0x00) && (map->bios_ptr[i+3] == 0x03)
&& (map->bios_ptr[i+4] == 0x80)
&& (map->bios_ptr[i+5] == 0x2F)
&& (map->bios_ptr[i+6] == 0x10)
&& (map->bios_ptr[i+7] == 0x10)
&& (map->bios_ptr[i+8] == 0x05)) {
nv_modeline_2_offset = (unsigned short) i;
break;
}
i++;
}
nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
map->nv_mode_table = (char *) std_vesa->sModelines;
if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {
map->nv_mode_table_2 = NULL;
} else {
map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;
}
if (map->nv_mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
close_vbios(map);
return 0;
}
map->mode_table_size = std_vesa->sHeader.usTable_Size;
}
/*
* Determine size of mode table
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
vbios_mode * mode_ptr = map->mode_table;
while (mode_ptr->mode != 0xff) {
map->mode_table_size++;
mode_ptr++;
}
}
/*
* Figure out what type of bios we have
* order of detection is important
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
map->bios = BT_3;
}
else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
map->bios = BT_2;
}
else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
map->bios = BT_1;
}
else {
printf("Unable to determine bios type.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
printf("Mode Table Entries: %u\n", map->mode_table_size);
return 0;
}
}
return map;
}
void close_vbios(vbios_map * map) {
FREE(map);
}
void unlock_vbios(vbios_map * map) {
map->unlocked = TRUE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
map->b1 = inb(0xcfe);
outl(0xcf8, 0x8000005a);
outb(0xcfe, 0x33);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
map->b1 = inb(0xcfd);
map->b2 = inb(0xcfe);
outl(0xcf8, 0x80000090);
outb(0xcfd, 0x33);
outb(0xcfe, 0x33);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("unlock PAM: (0x%08x)\n", t);
}
#endif
}
void relock_vbios(vbios_map * map) {
map->unlocked = FALSE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
outb(0xcfe, map->b1);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
outb(0xcfd, map->b1);
outb(0xcfe, map->b2);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("relock PAM: (0x%08x)\n", t);
}
#endif
}
void save_vbios(vbios_map * map)
{
map->bios_backup_ptr = malloc(VBIOS_SIZE);
bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);
}
void restore_vbios(vbios_map * map)
{
bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);
}
static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
{
UInt32 hbl, vbl, vfreq;
vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
vfreq = vbl * freq;
hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
+ (70 + 300000 / vfreq) / 16 + 0);
*vsyncstart = y;
*vsyncend = y + 3;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
*clock = (x + hbl) * vfreq / 1000;
}
void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)
{
UInt32 hbl, hbp, vbl, vsync, hperiod;
if (!(y % 3) && ((y * 4 / 3) == x))
vsync = 4;
else if (!(y % 9) && ((y * 16 / 9) == x))
vsync = 5;
else if (!(y % 10) && ((y * 16 / 10) == x))
vsync = 6;
else if (!(y % 4) && ((y * 5 / 4) == x))
vsync = 7;
else if (!(y % 9) && ((y * 15 / 9) == x))
vsync = 7;
else /* Custom */
vsync = 10;
if (!reduced) {
hperiod = (1000000/freq - 550) / (y + 3);
vbl = y + (550/hperiod) + 3;
hbp = 30 - ((300*hperiod)/1000);
hbl = (x * hbp) / (100 - hbp);
*vsyncstart = y + 6;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
} else {
hperiod = (1000000/freq - 460) / y;
vbl = y + 460/hperiod + 1;
hbl = 160;
*vsyncstart = y + 3;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - 32;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
}
*clock = (x + hbl) * 1000 / hperiod;
}
void set_mode(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
UInt32 xprev, yprev;
UInt32 i = 0, j;// patch first available mode
//for (i=0; i < map->mode_table_size; i++) {
//if (map->mode_table[0].mode == mode) {
switch(map->bios) {
case BT_1:
{
vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
if (bp) {
map->mode_table[i].bits_per_pixel = bp;
}
res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
res->x1 = (x & 0xff);
res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
res->y1 = (y & 0xff);
if (htotal)
res->x_total = ((htotal-x) & 0xff);
if (vtotal)
res->y_total = ((vtotal-y) & 0xff);
}
break;
case BT_2:
{
vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
res->xchars = x / 8;
res->ychars = y / 16 - 1;
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for(j=0; j < 3; j++) {
vbios_modeline_type2 * modeline = &res->modelines[j];
if (modeline->x1 == xprev && modeline->y1 == yprev) {
modeline->x1 = modeline->x2 = x-1;
modeline->y1 = modeline->y2 = y-1;
gtf_timings(x, y, freqs[j], &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank);
if (htotal)
modeline->htotal = htotal;
else
modeline->htotal = modeline->hblank;
if (vtotal)
modeline->vtotal = vtotal;
else
modeline->vtotal = modeline->vblank;
}
}
}
break;
case BT_3:
{
vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for (j=0; j < 3; j++) {
vbios_modeline_type3 * modeline = &res->modelines[j];
if (modeline->x1 == xprev && modeline->y1 == yprev) {
modeline->x1 = modeline->x2 = x-1;
modeline->y1 = modeline->y2 = y-1;
gtf_timings(x, y, freqs[j], &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank);
if (htotal)
modeline->htotal = htotal;
else
modeline->htotal = modeline->hblank;
if (vtotal)
modeline->vtotal = vtotal;
else
modeline->vtotal = modeline->vblank;
modeline->timing_h = y-1;
modeline->timing_v = x-1;
}
}
}
break;
case BT_ATI_1:
{
edid_mode mode;
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table;
mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
if ( mode_n == modeEndOfList )
{
minfo.XResolution = 1024;
minfo.YResolution = 768;
}
int m_status = getMode(&mode);
if (m_status || (mode.h_active != x)) {
vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
bzero(modeline, sizeof(vbios_modeline_type2));
cvt_timings(x, y, 60, &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank, FALSE);
mode.pixel_clock = modeline->clock /10;
mode.h_active = x;
mode.h_sync_offset = modeline->hsyncstart - x;
mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
mode.h_blanking = modeline->hblank - x;
mode.v_active = y;
mode.v_sync_offset = modeline->vsyncstart - y;
mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
mode.v_blanking = modeline->vblank - y;
free(modeline);
m_status = 0;
}
if (!m_status) {
while (i < (map->mode_table_size / sizeof(ATOM_MODE_TIMING)))
{
if (mode_timing[i].usCRTC_H_Disp == minfo.XResolution) {
mode_timing[i].usCRTC_H_Total = mode.h_active + mode.h_blanking;
mode_timing[i].usCRTC_H_Disp = mode.h_active;
mode_timing[i].usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset;
mode_timing[i].usCRTC_H_SyncWidth = mode.h_sync_width;
mode_timing[i].usCRTC_V_Total = mode.v_active + mode.v_blanking;
mode_timing[i].usCRTC_V_Disp = mode.v_active;
mode_timing[i].usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset;
mode_timing[i].usCRTC_V_SyncWidth = mode.v_sync_width;
mode_timing[i].usPixelClock = mode.pixel_clock;
}
i++;
}
}
}
break;
case BT_ATI_2:
{
edid_mode mode;
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table;
mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
if ( mode_n == modeEndOfList )
{
minfo.XResolution = 1024;
minfo.YResolution = 768;
}
int m_status = getMode(&mode);
if (m_status || (mode.h_active != x)) {
vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
bzero(modeline, sizeof(vbios_modeline_type2));
cvt_timings(x, y, 60, &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank, FALSE);
mode.pixel_clock = modeline->clock /10;
mode.h_active = x;
mode.h_sync_offset = modeline->hsyncstart - x;
mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
mode.h_blanking = modeline->hblank - x;
mode.v_active = y;
mode.v_sync_offset = modeline->vsyncstart - y;
mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
mode.v_blanking = modeline->vblank - y;
free(modeline);
m_status = 0;
}
if (!m_status) {
while (i < (map->mode_table_size / sizeof(ATOM_DTD_FORMAT)))
{
if (mode_timing[i].usHActive == minfo.XResolution) {
mode_timing[i].usHBlanking_Time = mode.h_blanking;
mode_timing[i].usHActive = mode.h_active;
mode_timing[i].usHSyncOffset = mode.h_sync_offset;
mode_timing[i].usHSyncWidth = mode.h_sync_width;
mode_timing[i].usVBlanking_Time = mode.v_blanking;
mode_timing[i].usVActive = mode.v_active;
mode_timing[i].usVSyncOffset = mode.v_sync_offset;
mode_timing[i].usVSyncWidth = mode.v_sync_width;
mode_timing[i].usPixClk = mode.pixel_clock;
}
i++;
}
}
}
break;
case BT_NVDA:
{
s_aspect aspect_ratio;
/*
* Get the aspect ratio for the requested mode
*/
if ((y * 16 / 9) == x) {
aspect_ratio.width = 16;
aspect_ratio.height = 9;
} else if ((y * 16 / 10) == x) {
aspect_ratio.width = 16;
aspect_ratio.height = 10;
} else if ((y * 5 / 4) == x) {
aspect_ratio.width = 5;
aspect_ratio.height = 4;
} else if ((y * 15 / 9) == x) {
aspect_ratio.width = 15;
aspect_ratio.height = 9;
} else {
aspect_ratio.width = 4;
aspect_ratio.height = 3;
}
NV_MODELINE *mode_timing = (NV_MODELINE *) map->nv_mode_table;
NV_MODELINE_2 *mode_timing_2 = (NV_MODELINE_2 *) map->nv_mode_table_2;
i = 0;
if (mode_timing_2[i].h_disp == 0x140) { //From 320x200 mode.
while (mode_timing_2[i].h_disp <= 0x800) {
vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));
bzero(modeliner, sizeof(vbios_modeline_type2));
x = mode_timing_2[i].h_disp;
y = x * aspect_ratio.height / aspect_ratio.width;
cvt_timings(x, y, 60, &modeliner->clock,
&modeliner->hsyncstart, &modeliner->hsyncend,
&modeliner->hblank, &modeliner->vsyncstart,
&modeliner->vsyncend, &modeliner->vblank, TRUE);
mode_timing_2[i].h_disp = x;
mode_timing_2[i].v_disp = y;
mode_timing_2[i].h_blank = modeliner->hblank - x;
mode_timing_2[i].h_syncoffset = modeliner->hsyncstart - x;
mode_timing_2[i].h_syncwidth = modeliner->hsyncend - modeliner->hsyncstart;
mode_timing_2[i].v_blank = modeliner->vblank - y;
i++;
free(modeliner);
}
}
i = 0;
while ((mode_timing[i].reserved3 & 0xff) == 0xff) {
x = mode_timing[i].usH_Active;
y = x * aspect_ratio.height / aspect_ratio.width;
vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));
bzero(modeliner, sizeof(vbios_modeline_type2));
cvt_timings(x, y, 60, &modeliner->clock,
&modeliner->hsyncstart, &modeliner->hsyncend,
&modeliner->hblank, &modeliner->vsyncstart,
&modeliner->vsyncend, &modeliner->vblank, FALSE);
mode_timing[i].usH_Total = x + modeliner->hblank;
mode_timing[i].usH_Active = x;
mode_timing[i].usH_Active_minus_One = x - 1;
mode_timing[i].usH_Active_minus_One_ = x - 1;
mode_timing[i].usH_SyncStart = modeliner->hsyncstart;
mode_timing[i].usH_SyncEnd = modeliner->hsyncend;
mode_timing[i].usV_Total = y + modeliner->vblank;
mode_timing[i].usV_Active = y;
mode_timing[i].usV_Active_minus_One = y - 1;
mode_timing[i].usV_Active_minus_One_ = y - 1;
mode_timing[i].usV_SyncStart = modeliner->vsyncend;
mode_timing[i].usV_SyncEnd = modeliner->vsyncend;
mode_timing[i].usPixel_Clock = modeliner->clock;
i++;
}
}
break;
case BT_UNKWN:
break;
}
//}
//}
}
branches/diebuche/i386/libsaio/915resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#ifndef __915_RESOLUTION_H
#define __915_RESOLUTION_H
#include "shortatombios.h"
#include "edid.h"
#define NEW(a) ((a *)(malloc(sizeof(a))))
#define FREE(a) (free(a))
#define VBIOS_START 0xc0000
#define VBIOS_SIZE 0x10000
#define FALSE 0
#define TRUE 1
#define MODE_TABLE_OFFSET_845G 617
#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
#define ATI_SIGNATURE2 "ATI Technologies Inc"
#define NVIDIA_SIGNATURE "NVIDIA Corp"
#define INTEL_SIGNATURE "Intel Corp"
typedef struct {
unsigned char width;
unsigned char height;
} s_aspect;
/*
* NVidia Defines and structures
*/
#define OFFSET_TO_VESA_TABLE_INDEX 2
typedef struct {
unsigned charucTable_Major;
unsigned charucTable_Minor;
unsigned charucTable_Rev;
unsigned shortusTable_Size;
} NV_COMMON_TABLE_HEADER;
typedef struct {
unsigned shortusPixel_Clock;
unsigned shortusH_Active;
unsigned short usH_Active_minus_One;
unsigned shortreserved1;
unsigned short usH_Active_minus_One_;
unsigned shortusH_SyncStart;
unsigned shortusH_SyncEnd;
unsigned shortusH_Total;
unsigned shortusV_Active;
unsigned short usV_Active_minus_One;
unsigned shortreserved2;
unsigned short usV_Active_minus_One_;
unsigned shortusV_SyncStart;
unsigned shortusV_SyncEnd;
unsigned shortusV_Total;
unsigned shortreserved3;
} NV_MODELINE;
typedef struct {
unsigned short h_disp;
unsigned short v_disp;
unsigned char h_blank;
unsigned char h_syncoffset;
unsigned char h_syncwidth;
unsigned char v_blank;
unsigned char v_syncwidth;
} NV_MODELINE_2;
typedef struct {
NV_COMMON_TABLE_HEADERsHeader;
NV_MODELINE*sModelines;
} NV_VESA_TABLE;
/*---*/
typedef enum {
CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G,
CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ,
CT_955X, CT_G965, CT_Q965, CT_965GM, CT_975X,
CT_P35, CT_X48, CT_B43, CT_Q45, CT_P45,
CT_GM45, CT_G41, CT_G31, CT_G45, CT_500
} chipset_type;
typedef enum {
BT_UNKWN, BT_1, BT_2, BT_3, BT_ATI_1, BT_ATI_2, BT_NVDA
} bios_type;
typedef struct {
unsigned char *base;
ATOM_ROM_HEADER *AtomRomHeader;
unsigned short *MasterCommandTables;
unsigned short *MasterDataTables;
} bios_tables_t;
typedef struct {
UInt8 mode;
UInt8 bits_per_pixel;
UInt16 resolution;
UInt8 unknown;
} __attribute__((packed)) vbios_mode;
typedef struct {
UInt8 unknow1[2];
UInt8 x1;
UInt8 x_total;
UInt8 x2;
UInt8 y1;
UInt8 y_total;
UInt8 y2;
} __attribute__((packed)) vbios_resolution_type1;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
} __attribute__((packed)) vbios_modeline_type2;
typedef struct {
UInt8 xchars;
UInt8 ychars;
UInt8 unknown[4];
vbios_modeline_type2 modelines[];
} __attribute__((packed)) vbios_resolution_type2;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
UInt16 timing_h;
UInt16 timing_v;
UInt8 unknown[6];
} __attribute__((packed)) vbios_modeline_type3;
typedef struct {
unsigned char unknown[6];
vbios_modeline_type3 modelines[];
} __attribute__((packed)) vbios_resolution_type3;
typedef struct {
UInt32 chipset_id;
chipset_type chipset;
bios_type bios;
bios_tables_t ati_tables;
UInt32 bios_fd;
unsigned char* bios_backup_ptr;
unsigned char* bios_ptr;
vbios_mode * mode_table;
char * ati_mode_table;
char * nv_mode_table;
char * nv_mode_table_2;
UInt32 mode_table_size;
UInt8 b1, b2;
UInt8 unlocked;
} vbios_map;
void display_map_info(vbios_map*);
vbios_map * open_vbios(chipset_type);
void close_vbios (vbios_map*);
void unlock_vbios(vbios_map*);
void relock_vbios(vbios_map*);
void save_vbios(vbios_map*);
void restore_vbios(vbios_map*);
void set_mode(vbios_map*, UInt32, UInt32, UInt32, UInt32, UInt32);
void list_modes(vbios_map *map, UInt32 raw);
#endif
branches/diebuche/i386/libsaio/ati_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* ati_resolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "ati_resolution.h"
char detect_ati_bios_type(vbios_map * map) {
return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;
}
vbios_map * open_ati_vbios(vbios_map * map, bios_tables_t ati_tables)
{
/*
* Locate the Standard VESA Table
*/
ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;
unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)ati_tables.MasterDataTables)->StandardVESA_Timing;
ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);
map->mode_table = (char *) &std_vesa->aModeTimings;
verbose("Standard VESA Table at offset * 0x%x\n", std_vesa_offset);
if (map->mode_table == 0) {
verbose("Unable to locate the mode table.\n");
verbose("Please run the program 'dump_bios' as root and\n");
verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
close_vbios(map);
return 0;
}
//Determine Size of the Table
map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);
/*
* Find out type of table and how many entries it has
*/
if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;
if (map->bios == BT_ATI_2) {
map->modeline_num = map->mode_table_size / sizeof(ATOM_DTD_FORMAT);
verbose("Using DTD Format modelines\n");
} else {
map->modeline_num = map->mode_table_size / sizeof(ATOM_MODE_TIMING);
verbose("Using Atom Mode Timing modelines\n");
}
return map;
}
bool ati_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)
{
ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->mode_table;
if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usCRTC_H_Disp >= 640 )) {
verbose("Mode %dx%d -> %dx%d\n",mode_timing[idx].usCRTC_H_Disp,mode_timing[idx].usCRTC_V_Disp,
*x, *y);
mode_timing[idx].usCRTC_H_Disp = *x;
mode_timing[idx].usCRTC_V_Disp = *y;
}
*x = mode_timing[idx + 1].usCRTC_H_Disp;
*y = mode_timing[idx + 1].usCRTC_V_Disp;
return TRUE;
}
bool ati_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)
{
ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->mode_table;
if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usHActive >= 640 )) {
verbose("Mode %dx%d -> %dx%d\n", mode_timing[idx].usHActive, mode_timing[idx].usHActive,
*x, *y);
mode_timing[idx].usHActive = *x;
mode_timing[idx].usVActive = *y;
}
*x = mode_timing[idx + 1].usHActive;
*y = mode_timing[idx + 1].usVActive;
return TRUE;
}
branches/diebuche/i386/libsaio/ati_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
* ati_resolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _ATI_RESOLUTION_H_
#define _ATI_RESOLUTION_H_
#include "libsaio.h"
#include "autoresolution.h"
#include "shortatombios.h"
#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
#define ATI_SIGNATURE2 "ATI Technologies Inc"
typedef struct {
unsigned char *base;
ATOM_ROM_HEADER *AtomRomHeader;
unsigned short *MasterCommandTables;
unsigned short *MasterDataTables;
} bios_tables_t;
char detect_ati_bios_type(vbios_map * map);
vbios_map * open_ati_vbios(vbios_map * map, bios_tables_t ati_tables);
bool ati_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y);
bool ati_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y);
#endif
branches/diebuche/i386/libsaio/vbe.c
2929
3030
3131
32
3233
3334
3435
#include "libsaio.h"
#include "edid.h"
#include "vbe.h"
#include "autoresolution.h"
/*
* Various inline routines for video I/O
branches/diebuche/i386/libsaio/vbe.h
176176
177177
178178
179
179
180
181
180182
181183
182184
maGraphicsModeBit = (1 << 4), /* 1 = graphics; 0 = text */
maModeIsNotVGACompatableBit = (1 << 5), /* 1 = not compat; 0 = compat */
maVGAMemoryModeNotAvailBit = (1 << 6), /* 1 = not avail; 0 = avail */
maLinearFrameBufferAvailBit = (1 << 7) /* 1 = avail; 0 = not avail */
maLinearFrameBufferAvailBit = (1 << 7), /* 1 = avail; 0 = not avail */
maDoubleScanAvailBit= (1 << 8), /* 1 = avail; 0 = not avail */
maInterlacedAvailBit= (1 << 9) /* 1 = avail; 0 = not avail */
};
/*
branches/diebuche/i386/libsaio/Makefile
4242
4343
4444
45
46
45
46
47
48
4749
4850
4951
cpu.o platform.o dsdt_patcher.o \
smbios_patcher.o fake_efi.o ext2fs.o \
hpet.o spd.o usb.o pci_setup.o \
device_inject.o nvidia.o ati.o pci_root.o \
convert.o mem.o 915resolution.o edid.o
device_inject.o nvidia.o ati.o \
gma_resolution.o ati_resolution.o nvidia_resolution.o \
pci_root.o convert.o mem.o \
autoresolution.o edid.o
SAIO_EXTERN_OBJS = console.o
branches/diebuche/i386/libsaio/autoresolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#include "libsaio.h"
#include "autoresolution.h"
#include "nvidia_resolution.h"
#include "ati_resolution.h"
#include "gma_resolution.h"
#include "../boot2/graphics.h"
char * chipset_type_names[] = {
"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
"946GZ", "955X", "G965", "Q965", "965GM", "975X",
"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
};
UInt32 get_chipset_id(void) {
outl(0xcf8, 0x80000000);
return inl(0xcfc);
}
chipset_type get_chipset(UInt32 id) {
chipset_type type;
switch (id) {
case 0x35758086:
type = CT_830;
break;
case 0x25608086:
type = CT_845G;
break;
case 0x35808086:
type = CT_855GM;
break;
case 0x25708086:
type = CT_865G;
break;
case 0x25808086:
type = CT_915G;
break;
case 0x25908086:
type = CT_915GM;
break;
case 0x27708086:
type = CT_945G;
break;
case 0x27748086:
type = CT_955X;
break;
case 0x277c8086:
type = CT_975X;
break;
case 0x27a08086:
type = CT_945GM;
break;
case 0x27ac8086:
type = CT_945GME;
break;
case 0x29708086:
type = CT_946GZ;
break;
case 0x29a08086:
type = CT_G965;
break;
case 0x29908086:
type = CT_Q965;
break;
case 0x2a008086:
type = CT_965GM;
break;
case 0x29e08086:
type = CT_X48;
break;
case 0x2a408086:
type = CT_GM45;
break;
case 0x2e108086:
case 0X2e908086:
type = CT_B43;
break;
case 0x2e208086:
type = CT_P45;
break;
case 0x2e308086:
type = CT_G41;
break;
case 0x29c08086:
type = CT_G31;
break;
case 0x29208086:
type = CT_G45;
break;
case 0x81008086:
type = CT_500;
break;
default:
type = CT_UNKWN;
break;
}
return type;
}
void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
{
UInt32 hbl, vbl, vfreq;
vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
vfreq = vbl * freq;
hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
+ (70 + 300000 / vfreq) / 16 + 0);
*vsyncstart = y;
*vsyncend = y + 3;
*vblank = vbl;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ;
*hsyncend = x + hbl / 2;
*hblank = x + hbl;
*clock = (x + hbl) * vfreq / 1000;
}
void get_aspect_ratio(s_aspect* aspect, UInt32 x, UInt32 y)
{
if ((y * 16 / 9) == x) {
aspect->width = 16;
aspect->height = 9;
} else if ((y * 16 / 10) == x) {
aspect->width = 16;
aspect->height = 10;
} else if ((y * 5 / 4) == x) {
aspect->width = 5;
aspect->height = 4;
} else if ((y * 15 / 9) == x) {
aspect->width = 15;
aspect->height = 9;
} else {
aspect->width = 4;
aspect->height = 3;
}
verbose("Aspect Ratio is %d/%d\n", aspect->width, aspect->height);
}
void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)
{
UInt32 hbl, hbp, vbl, vsync, hperiod;
if (!(y % 3) && ((y * 4 / 3) == x))
vsync = 4;
else if (!(y % 9) && ((y * 16 / 9) == x))
vsync = 5;
else if (!(y % 10) && ((y * 16 / 10) == x))
vsync = 6;
else if (!(y % 4) && ((y * 5 / 4) == x))
vsync = 7;
else if (!(y % 9) && ((y * 15 / 9) == x))
vsync = 7;
else /* Custom */
vsync = 10;
if (!reduced) {
hperiod = (1000000/freq - 550) / (y + 3);
vbl = y + (550/hperiod) + 3;
hbp = 30 - ((300*hperiod)/1000);
hbl = (x * hbp) / (100 - hbp);
*vsyncstart = y + 6;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
} else {
hperiod = (1000000/freq - 460) / y;
vbl = y + 460/hperiod + 1;
hbl = 160;
*vsyncstart = y + 3;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - 32;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
}
*clock = (x + hbl) * 1000 / hperiod;
}
void close_vbios(vbios_map * map);
vbios_map * open_vbios(chipset_type forced_chipset) {
UInt32 z;
vbios_map * map = NEW(vbios_map);
for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
/*
* Determine chipset
*/
if (forced_chipset == CT_UNKWN) {
map->chipset_id = get_chipset_id();
map->chipset = get_chipset(map->chipset_id);
verbose("Chipset is %s (pci id 0x%x)\n",chipset_type_names[map->chipset], map->chipset_id);
}
else if (forced_chipset != CT_UNKWN) {
map->chipset = forced_chipset;
}
else {
map->chipset = CT_915GM;
}
/*
* Map the video bios to memory
*/
map->bios_ptr=(unsigned char*)VBIOS_START;
/*
* check if we have ATI Radeon and open atombios
*/
bios_tables_t ati_tables;
ati_tables.base = map->bios_ptr;
ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
if (strcmp ((char *) ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") == 0) {
map->bios = BT_ATI_1;
verbose("We have an AtomBios Card\n");
return open_ati_vbios(map, ati_tables);
}
/*
* check if we have NVidia
*/
if (map->bios != BT_ATI_1) {
int i = 0;
while (i < 512) { // we don't need to look through the whole bios, just the firs 512 bytes
if ((map->bios_ptr[i] == 'N')
&& (map->bios_ptr[i+1] == 'V')
&& (map->bios_ptr[i+2] == 'I')
&& (map->bios_ptr[i+3] == 'D'))
{
map->bios = BT_NVDA;
verbose("We have an NVIDIA Card\n");
return open_nvidia_vbios(map);
break;
}
i++;
}
}
/*
* check if we have Intel
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA)) {
int i = 0;
while (i < VBIOS_SIZE) { // we don't need to look through the whole bios, just the firs 512 bytes
if ((map->bios_ptr[i] == 'I')
&& (map->bios_ptr[i+1] == 'n')
&& (map->bios_ptr[i+2] == 't')
&& (map->bios_ptr[i+3] == 'e')
&& (map->bios_ptr[i+4] == 'l'))
{
map->bios = BT_1;
verbose("We have an Intel Card\n");
return open_intel_vbios(map);
break;
}
i++;
}
}
/*
* Unidentified Chipset
*/
if (map->chipset == CT_UNKWN) {
verbose("Unknown chipset type and unrecognized bios.\n");
verbose("autoresolution only works with Intel 800/900 series graphic chipsets.\n");
verbose("Chipset Id: %x\n", map->chipset_id);
close_vbios(map);
return 0;
}
/*
* Should never get there
*/
return 0;
}
void close_vbios(vbios_map * map) {
if (autoResolution == TRUE) autoResolution = FALSE;
FREE(map);
}
void unlock_vbios(vbios_map * map) {
map->unlocked = TRUE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
map->b1 = inb(0xcfe);
outl(0xcf8, 0x8000005a);
outb(0xcfe, 0x33);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
map->b1 = inb(0xcfd);
map->b2 = inb(0xcfe);
outl(0xcf8, 0x80000090);
outb(0xcfd, 0x33);
outb(0xcfe, 0x33);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("unlock PAM: (0x%08x)\n", t);
}
#endif
}
void relock_vbios(vbios_map * map) {
map->unlocked = FALSE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
outb(0xcfe, map->b1);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
outb(0xcfd, map->b1);
outb(0xcfe, map->b2);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("relock PAM: (0x%08x)\n", t);
}
#endif
}
void save_vbios(vbios_map * map)
{
map->bios_backup_ptr = malloc(VBIOS_SIZE);
bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);
}
void restore_vbios(vbios_map * map)
{
bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);
}
void patch_vbios(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
UInt32 i = 0;
bool err = TRUE;
/*
* Get the aspect ratio for the requested mode
*/
get_aspect_ratio(&map->aspect_ratio, x, y);
i = x = y = 0;
if (map->bios != BT_NVDA) {
while (i < map->modeline_num) {
if (x == 1400) x = 1440;
if (x == 1600) x = 1680;
y = x * map->aspect_ratio.height / map->aspect_ratio.width;
switch (map->bios) {
case BT_1:
intel_set_mode_1(map, i, &x, &y);
break;
case BT_2:
intel_set_mode_2(map, i, &x, &y);
break;
case BT_3:
intel_set_mode_3(map, i, &x, &y);
break;
case BT_ATI_1:
ati_set_mode_1(map, i, &x, &y);
break;
case BT_ATI_2:
ati_set_mode_2(map, i, &x, &y);
break;
default:
break;
}
i++;
}
}
if (map->bios == BT_NVDA) {
err = TRUE;
x = y = 0;
while (err == TRUE) {
if (x == 1400) x = 1440;
if (x == 1600) x = 1680;
y = x * map->aspect_ratio.height / map->aspect_ratio.width;
err = nvidia_set_mode(map, i, &x, &y, MAIN_VESA_TABLE);
}
err = TRUE;
x = y = 0;
while (err == TRUE) {
if (x == 1400) x = 1440;
if (x == 1600) x = 1680;
y = x * map->aspect_ratio.height / map->aspect_ratio.width;
err = nvidia_set_mode(map, i, &x, &y, SECOND_VESA_TABLE);
}
}
}
branches/diebuche/i386/libsaio/autoresolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#ifndef __915_RESOLUTION_H
#define __915_RESOLUTION_H
#include "edid.h"
#define NEW(a) ((a *)(malloc(sizeof(a))))
#define FREE(a) (free(a))
#define VBIOS_START 0xc0000
#define VBIOS_SIZE 0x10000
#define FALSE 0
#define TRUE 1
typedef struct {
unsigned char width;
unsigned char height;
} s_aspect;
typedef enum {
CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G,
CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ,
CT_955X, CT_G965, CT_Q965, CT_965GM, CT_975X,
CT_P35, CT_X48, CT_B43, CT_Q45, CT_P45,
CT_GM45, CT_G41, CT_G31, CT_G45, CT_500
} chipset_type;
typedef enum {
BT_UNKWN, BT_1, BT_2, BT_3, BT_ATI_1, BT_ATI_2, BT_NVDA
} bios_type;
typedef struct {
UInt32 chipset_id;
chipset_type chipset;
bios_type bios;
UInt32 bios_fd;
unsigned char* bios_backup_ptr;
unsigned char* bios_ptr;
char * mode_table;
char * nv_mode_table_2;
UInt32 mode_table_size;
UInt32 modeline_num;
UInt8 b1, b2;
s_aspect aspect_ratio;
UInt8 unlocked;
} vbios_map;
vbios_map * open_vbios(chipset_type);
void close_vbios (vbios_map*);
void unlock_vbios(vbios_map*);
void relock_vbios(vbios_map*);
void save_vbios(vbios_map*);
void restore_vbios(vbios_map*);
void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank);
/*void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, BOOL reduced);*/
void patch_vbios(vbios_map*, UInt32, UInt32, UInt32, UInt32, UInt32);
#endif
branches/diebuche/i386/libsaio/nvidia_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* nvidia_resolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "nvidia_resolution.h"
vbios_map * open_nvidia_vbios(vbios_map *map)
{
unsigned short nv_data_table_offset = 0;
unsigned short nv_modeline_2_offset = 0;
unsigned short * nv_data_table = NULL;
NV_VESA_TABLE * std_vesa;
/*
* Locate the VESA Tables
*/
int i = 0;
while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only
if ((map->bios_ptr[i] == 0x44)
&& (map->bios_ptr[i+1] == 0x01)
&& (map->bios_ptr[i+2] == 0x04)
&& (map->bios_ptr[i+3] == 0x00)) {
nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
break;
}
i++;
}
//Second VESA Table on some nVidia 8xxx 9xxx and GT
while (i < VBIOS_SIZE) { //We don't know how to locate it other way
if ((map->bios_ptr[i] == 0x40) && (map->bios_ptr[i+1] == 0x01) //this is the first 320x200 modeline.
&& (map->bios_ptr[i+2] == 0xC8) && (map->bios_ptr[i+3] == 0x00)
&& (map->bios_ptr[i+4] == 0x28)
&& (map->bios_ptr[i+5] == 0x18)
&& (map->bios_ptr[i+6] == 0x08)
&& (map->bios_ptr[i+7] == 0x08)) {
nv_modeline_2_offset = (unsigned short) i;
break;
}
i++;
}
nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
map->mode_table = (char *) std_vesa->sModelines;
verbose("First Standard VESA Table at offset 0x%x\n", *nv_data_table);
if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {
map->nv_mode_table_2 = NULL;
verbose("There is no Second Standard VESA Table to patch\n");
} else {
map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;
verbose("Second Standard VESA Table at offset 0x%x\n", nv_modeline_2_offset);
}
if (map->mode_table == NULL) {
verbose("Unable to locate the mode table.\n");
verbose("Please run the program 'dump_bios' as root and\n");
verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
close_vbios(map);
return 0;
}
//This won't be used as there is no garanty this is right
map->mode_table_size = std_vesa->sHeader.usTable_Size;
return map;
}
bool nvidia_set_mode(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y, char Type)
{
if (Type == MAIN_VESA_TABLE) {
NV_MODELINE * mode_timing = (NV_MODELINE *) map->mode_table;
if ((mode_timing[idx].reserved3 & 0xff) != 0xff) return FALSE;
if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usH_Active >= 640 )) {
verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].usH_Active, mode_timing[idx].usV_Active,
*x, *y);
mode_timing[idx].usH_Active = *x;
mode_timing[idx].usH_Active_minus_One = *x - 1;
mode_timing[idx].usH_Active_minus_One_ = *x - 1;
mode_timing[idx].usV_Active = *y;
mode_timing[idx].usV_Active_minus_One = *y - 1;
mode_timing[idx].usV_Active_minus_One_ = *y - 1;
}
*x = mode_timing[idx + 1].usH_Active;
*y = mode_timing[idx + 1].usV_Active;
}
if (Type == SECOND_VESA_TABLE) {
NV_MODELINE_2 * mode_timing = (NV_MODELINE_2 *) map->nv_mode_table_2;
if (mode_timing[idx].h_disp > 0x800) return FALSE;
if ((*x != 0) && (*y != 0) && ( mode_timing[idx].h_disp >= 640 )) {
verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].h_disp, mode_timing[idx].v_disp,
*x, *y);
mode_timing[idx].h_disp = *x;
mode_timing[idx].v_disp = *y;
}
*x = mode_timing[idx + 1].h_disp;
*y = mode_timing[idx + 1].v_disp;
}
return TRUE;
}
branches/diebuche/i386/libsaio/nvidia_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* nviviaresolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _NVDA_RESOLUTION_HEADER_
#define _NVDA_RESOLUTION_HEADER_
#include "libsaio.h"
#include "autoresolution.h"
#define NVIDIA_SIGNATURE "NVIDIA Corp"
#define OFFSET_TO_VESA_TABLE_INDEX 2
#define MAIN_VESA_TABLE 0
#define SECOND_VESA_TABLE 1
typedef struct {
unsigned charucTable_Major; //These names are probably wrong
unsigned charucTable_Minor;
unsigned charucTable_Rev;
unsigned shortusTable_Size;
} NV_COMMON_TABLE_HEADER;
typedef struct {
unsigned shortusPixel_Clock;
unsigned shortusH_Active;
unsigned short usH_Active_minus_One;
unsigned shortreserved1;
unsigned short usH_Active_minus_One_;
unsigned shortusH_SyncStart;
unsigned shortusH_SyncEnd;
unsigned shortusH_Total;
unsigned shortusV_Active;
unsigned short usV_Active_minus_One;
unsigned shortreserved2;
unsigned short usV_Active_minus_One_;
unsigned shortusV_SyncStart;
unsigned shortusV_SyncEnd;
unsigned shortusV_Total;
unsigned shortreserved3;
} NV_MODELINE;
typedef struct {
unsigned short h_disp;
unsigned short v_disp;
unsigned char h_blank;
unsigned char h_syncoffset;
unsigned char h_syncwidth;
unsigned char v_blank;
//unsigned char v_syncwidth;
unsigned char flags; //looks like flags & 1 means "Graphics Mode", to oppose to "Console Mode"
//on 7xxx the high four bits look like a mode id number.
//on 8xxx only the low four bits are used, standard graphics mode are always 5.
//it can be 1 (1400x1050 and 2048x1536) (HSync High, VSync High ?)
// 3 (1440x900, 1680x1050 and 1920x1200) (Hsync High, VSync Low ?)
// 3 (Standard Timings) (Hsync Low, VSync High ?)
// or 7 (1280x800 and 768x340) (Hync Low, VSync Low ?)
} NV_MODELINE_2;
typedef struct {
NV_COMMON_TABLE_HEADERsHeader;
NV_MODELINE*sModelines;
} NV_VESA_TABLE;
vbios_map * open_nvidia_vbios(vbios_map *map);
bool nvidia_set_mode(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y, char Type);
#endif
branches/diebuche/i386/libsaio/edid.c
1212
1313
1414
15
1615
16
1717
1818
1919
......
5050
5151
5252
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
7753
7854
7955
......
150126
151127
152128
153
129
130
131
132
154133
155134
156135
#include "edid.h"
#include "vbe.h"
#include "bootstruct.h"
//#include "graphics.h"
//static biosBuf_t bb;
UInt32 xResolution = 0;
}
int getMode(edid_mode *mode)
{
unsigned char* edidInfo = readEDID();
if(!edidInfo) return 1;
mode->pixel_clock = (edidInfo[55] << 8) | edidInfo[54];
mode->h_active = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
mode->h_blanking = ((edidInfo[58] & 0x0F) << 8) | edidInfo[57];
mode->v_active = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
mode->v_blanking = ((edidInfo[61] & 0x0F) << 8) | edidInfo[60];
mode->h_sync_offset = ((edidInfo[65] & 0xC0) >> 2) | edidInfo[62];
mode->h_sync_width = (edidInfo[65] & 0x30) | edidInfo[63];
mode->v_sync_offset = (edidInfo[65] & 0x0C) | ((edidInfo[64] & 0x0C) >> 2);
mode->v_sync_width = ((edidInfo[65] & 0x3) << 2) | (edidInfo[64] & 0x03);
free( edidInfo );
if(!mode->h_active) return 1;
return 0;
}
unsigned char* readEDID()
{
printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
return 0;
}
} else return 0;
} else {
return 0;
}
blocks_left = 0;
} while(blocks_left);
branches/diebuche/i386/libsaio/edid.h
3434
3535
3636
37
3837
3938
unsigned char* readEDID();
void getResolution(UInt32* x, UInt32* y, UInt32* bp);
int getMode(edid_mode* mode);
#endif
branches/diebuche/i386/libsaio/gma_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
* gma_resolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "gma_resolution.h"
char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
int freqs[] = { 60, 75, 85 };
vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
return ptr;
}
char detect_bios_type(vbios_map * map, char modeline, int entry_size) {
UInt32 i;
UInt16 r1, r2;
vbios_mode * mode_table = (vbios_mode *)map->mode_table;
r1 = r2 = 32000;
for (i=0; i < map->mode_table_size; i++) {
if (mode_table[i].resolution <= r1) {
r1 = mode_table[i].resolution;
}
else {
if (mode_table[i].resolution <= r2) {
r2 = mode_table[i].resolution;
}
}
/*printf("r1 = %d r2 = %d\n", r1, r2);*/
}
return (r2-r1-6) % entry_size == 0;
}
vbios_map * open_intel_vbios(vbios_map *map)
{
/*
* Find the location of the Mode Table
*/
unsigned char* p = map->bios_ptr + 16;
unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
while (p < limit && map->mode_table == 0) {
vbios_mode* mode_ptr = (vbios_mode*) p;
if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
map->mode_table = (char *)mode_ptr;
}
p++;
}
if (map->mode_table == 0) {
verbose("Unable to locate the mode table.\n");
verbose("Please run the program 'dump_bios' as root and\n");
verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
close_vbios(map);
return 0;
}
/*
* Determine size of mode table
*/
vbios_mode * mode_ptr = (vbios_mode *)map->mode_table;
while (mode_ptr->mode != 0xff) {
map->mode_table_size++;
mode_ptr++;
}
map->modeline_num = map->mode_table_size;
/*
* Figure out what type of bios we have
* order of detection is important
*/
if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
map->bios = BT_3;
}
else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
map->bios = BT_2;
}
else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
map->bios = BT_1;
}
else {
verbose("Unable to determine bios type.\n");
verbose("Please run the program 'dump_bios' as root and\n");
verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
return 0;
}
return map;
}
bool intel_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)
{
vbios_mode *mode_timing = (vbios_mode *) map->mode_table;
vbios_resolution_type1 * res = map_type1_resolution(map, mode_timing[idx].resolution);
UInt32 actual_x = ((res->x2 & 0xf0) << 4) | (res->x1 & 0xff);
UInt32 actual_y = ((res->y2 & 0xf0) << 4) | (res->y1 & 0xff);
if ((*x != 0) && (*y != 0) && ( actual_x >= 640 )) {
printf("Mode %dx%d -> %dx%d ", actual_x, actual_y, *x, *y);
res->x2 = (res->x2 & 0x0f) | ((*x >> 4) & 0xf0);
res->x1 = (*x & 0xff);
res->y2 = ((*y >> 4) & 0xf0);
res->y1 = (*y & 0xff);
}
res = map_type1_resolution(map, mode_timing[idx + 1].resolution);
actual_x = ((res->x2 & 0xf0) << 4) | (res->x1 & 0xff);
actual_y = ((res->y2 & 0xf0) << 4) | (res->y1 & 0xff);
*x = actual_x;
*y = actual_y;
return TRUE;
}
bool intel_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)
{
UInt32 xprev, yprev, j = 0;
vbios_mode *mode_timing = (vbios_mode *) map->mode_table;
vbios_resolution_type2 * res = map_type2_resolution(map, mode_timing[idx].resolution);
if ((*x != 0) && (*y != 0) && ((res->modelines[0].x1 + 1) >= 640 )) {
printf("Mode %dx%d -> %dx%d ", res->modelines[0].x1 + 1, res->modelines[0].y1 + 1, *x, *y);
res->xchars = *x / 8;
res->ychars = *y / 16 - 1;
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for(j = 0; j < 3; j++) {
vbios_modeline_type2 * mode = &res->modelines[j];
if (mode->x1 == xprev && mode->y1 == yprev) {
mode->x1 = mode->x2 = *x-1;
mode->y1 = mode->y2 = *y-1;
gtf_timings(*x, *y, freqs[j], &mode->clock,
&mode->hsyncstart, &mode->hsyncend,
&mode->hblank, &mode->vsyncstart,
&mode->vsyncend, &mode->vblank);
mode->htotal = mode->hblank;
mode->vtotal = mode->vblank;
}
}
}
res = map_type2_resolution(map, mode_timing[idx + 1].resolution);
*x = res->modelines[0].x1 + 1;
*y = res->modelines[0].y1 + 1;
return TRUE;
}
bool intel_set_mode_3(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)
{
UInt32 xprev, yprev, j = 0;
vbios_mode *mode_timing = (vbios_mode *) map->mode_table;
vbios_resolution_type3 * res = map_type3_resolution(map, mode_timing[idx].resolution);
if ((*x != 0) && (*y != 0) && ((res->modelines[0].x1 + 1) >= 640 )) {
printf("Mode %dx%d -> %dx%d ", res->modelines[0].x1 + 1, res->modelines[0].y1 + 1, *x, *y);
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for(j = 0; j < 3; j++) {
vbios_modeline_type3 * mode = &res->modelines[j];
if (mode->x1 == xprev && mode->y1 == yprev) {
mode->x1 = mode->x2 = *x-1;
mode->y1 = mode->y2 = *y-1;
gtf_timings(*x, *y, freqs[j], &mode->clock,
&mode->hsyncstart, &mode->hsyncend,
&mode->hblank, &mode->vsyncstart,
&mode->vsyncend, &mode->vblank);
mode->htotal = mode->hblank;
mode->vtotal = mode->vblank;
mode->timing_h = *y-1;
mode->timing_v = *x-1;
}
}
}
res = map_type3_resolution(map, mode_timing[idx + 1].resolution);
*x = res->modelines[0].x1 + 1;
*y = res->modelines[0].y1 + 1;
return TRUE;
}
branches/diebuche/i386/libsaio/gma_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* gma_resolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _GMA_RESOLUTION_H_
#define _GMA_RESOLTUION_H_
#include "libsaio.h"
#include "autoresolution.h"
#define MODE_TABLE_OFFSET_845G 617
#define INTEL_SIGNATURE "Intel Corp"
typedef struct {
UInt8 mode;
UInt8 bits_per_pixel;
UInt16 resolution;
UInt8 unknown;
} __attribute__((packed)) vbios_mode;
typedef struct {
UInt8 unknow1[2];
UInt8 x1;
UInt8 x_total;
UInt8 x2;
UInt8 y1;
UInt8 y_total;
UInt8 y2;
} __attribute__((packed)) vbios_resolution_type1;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
} __attribute__((packed)) vbios_modeline_type2;
typedef struct {
UInt8 xchars;
UInt8 ychars;
UInt8 unknown[4];
vbios_modeline_type2 modelines[];
} __attribute__((packed)) vbios_resolution_type2;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
UInt16 timing_h;
UInt16 timing_v;
UInt8 unknown[6];
} __attribute__((packed)) vbios_modeline_type3;
typedef struct {
unsigned char unknown[6];
vbios_modeline_type3 modelines[];
} __attribute__((packed)) vbios_resolution_type3;
vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res);
vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res);
vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res);
char detect_bios_type(vbios_map * map, char modeline, int entry_size);
vbios_map * open_intel_vbios(vbios_map *);
bool intel_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y);
bool intel_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y);
bool intel_set_mode_3(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y);
#endif
branches/diebuche/i386/boot2/graphics.c
387387
388388
389389
390
391
390392
391393
392394
......
429431
430432
431433
432
433434
434
435435
436436
437437
......
461461
462462
463463
464
464
465
466
467
465468
466469
467470
break;
}
if (refreshRate != 60) refreshRate = 60;
//
// FIXME : generateCRTCTiming() causes crash.
//
err = setVBEMode( mode | kLinearFrameBufferBit, NULL );
if ( err != errSuccess )
{
break;
}
// Set 8-bit color palette.
bootArgs->Video.v_depth = minfo.BitsPerPixel;
bootArgs->Video.v_rowBytes = minfo.BytesPerScanline;
bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
#if DEBUG
gui.screen.mm= minfo.MemoryModel;
gui.screen.attr= minfo.ModeAttributes;
#endif
}
while ( 0 );
branches/diebuche/i386/boot2/boot.c
5959
6060
6161
62
62
6363
6464
6565
......
131131
132132
133133
134
134
135135
136136
137137
138138
139
140
141
142
143139
144140
145141
......
167163
168164
169165
170
171
172
173
174
175
176
166
177167
178168
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
169
201170
202
203
204171
205172
206173
......
226193
227194
228195
229
230
231
232
233
234
235
236
237196
238197
239198
......
371330
372331
373332
374
333
375334
376335
377336
378337
379338
339
340
341
342
380343
344
381345
382
346
347
383348
384
385
349
350
351
386352
387353
388354
389
355
390356
391
392
393
394
395
396
397
398
399
400
401
402
403
404
357
358
359
360
361
362
363
364
365
366
367
368
369
405370
406371
407372
......
474439
475440
476441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
477486
478487
479488
......
656665
657666
658667
659
668
660669
661670
662671
#include "gui.h"
#include "platform.h"
#include "edid.h"
#include "915resolution.h"
#include "autoresolution.h"
long gBootMode; /* defaults to 0 == kBootModeNormal */
bool gOverrideKernel;
//==========================================================================
// execKernel - Load the kernel image (mach-o) and jump to its entry point.
static int ExecKernel(void *binary, vbios_map *map)
static int ExecKernel(void *binary)
{
entry_t kernelEntry;
int ret;
UInt32 params[4];
int count;
params[3] = 0;
bootArgs->kaddr = bootArgs->ksize = 0;
ret = DecodeKernel(binary,
sleep(kBootErrorTimeout);
}
//if the vbios patch have been applied restore it before performing fake efi stuff
if (autoResolution == TRUE) {
unlock_vbios(map);
restore_vbios(map);
relock_vbios(map);
}
setupFakeEfi();
//Reapply the vbios patch before setting mode for boot graphics
if (autoResolution == TRUE) {
count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
if ( count < 3 ) {
getResolution(&params[0], &params[1], &params[2]);
}
else
{
if ( params[2] == 256 ) params[2] = 8;
if ( params[2] == 555 ) params[2] = 16;
if ( params[2] == 888 ) params[2] = 32;
}
if (params[0]!=0 && params[1]!=0) {
unlock_vbios(map);
set_mode(map, params[0], params[1], params[2], 0, 0);
relock_vbios(map);
}
}
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
// Cleanup the PXE base code.
if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
else
drawBootGraphics();
//Boot Graphis are set finalize and free vbios patch structures
if (autoResolution == TRUE) {
unlock_vbios(map);
restore_vbios(map);
relock_vbios(map);
close_vbios(map);
}
finalizeBootStruct();
// Jump to kernel's entry point. There's no going back now.
UInt32 params[4];
int count;
params[3] = 0;
vbios_map * map = open_vbios(CT_UNKWN);
autoResolution = TRUE;
// Override AutoResolution default
getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig);
vbios_map * map = open_vbios(CT_UNKWN);
//Saving the bios in case we have to unpatch it
save_vbios(map);
if (autoResolution == TRUE) {
//Get Resolution from Graphics Mode key
count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
if ( count < 3 )
if ( count < 3 ){
//If no Graphics Mode key, get from EDID
getResolution(&params[0], &params[1], &params[2]);
else
{
verbose("EDID Resolution: %dx%d\n",params[0], params[1]);
}
} else {
if ( params[2] == 256 ) params[2] = 8;
if ( params[2] == 555 ) params[2] = 16;
if ( params[2] == 888 ) params[2] = 32;
}
}
if (params[0]!=0 && params[1]!=0) {
vbios_map * map = open_vbios(CT_UNKWN);
unlock_vbios(map);
save_vbios(map);
set_mode(map, params[0], params[1], params[2], 0, 0);
relock_vbios(map);
verbose("Patched resolution mode to %dx%d.\n", params[0], params[1]);
}
}
if (params[0]!=0 && params[1]!=0) {
unlock_vbios(map);
patch_vbios(map, params[0], params[1], params[2], 0, 0);
relock_vbios(map);
#if DEBUG
printf("Press Any Key...\n");
getc();
#endif
}
if (useGUI) {
/* XXX AsereBLN handle error */
updateVRAM();
}
/*
* AutoResolution - Reapply the patch or cancel if Graphics Mode was incorrect
* or EDID Info was insane
*/
getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig);
//Restore the vbios for Cancelation
if ((autoResolution == FALSE) && map) {
unlock_vbios(map);
restore_vbios(map);
relock_vbios(map);
close_vbios(map);
}
if ((autoResolution == TRUE) && map) {
//Reapply patch in case resolution have changed
count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
if ( count < 3 ) {
getResolution(&params[0], &params[1], &params[2]);
}
else
{
if ( params[2] == 256 ) params[2] = 8;
if ( params[2] == 555 ) params[2] = 16;
if ( params[2] == 888 ) params[2] = 32;
}
if (params[0]!=0 && params[1]!=0) {
unlock_vbios(map);
patch_vbios(map, params[0], params[1], params[2], 0, 0);
relock_vbios(map);
close_vbios(map);
}
}
// Find out which version mac os we're booting.
if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) {
if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) {
}
} else {
/* Won't return if successful. */
ret = ExecKernel(binary, map);
ret = ExecKernel(binary);
}
}
branches/diebuche/i386/boot2/gui.c
1212
1313
1414
15
1516
1617
1718
......
557558
558559
559560
560
561
561562
562563
563564
......
568569
569570
570571
571
572
573
572574
573575
574576
......
578580
579581
580582
581
582
583
584
585
586
587
588
589
590
591
592
583
584
585
586
587
588
589
590
591
593592
594593
595594
......
768767
769768
770769
770
771
772
773
771774
772775
773776
......
17061709
17071710
17081711
1709
1712
17101713
17111714
17121715
......
17171720
17181721
17191722
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
17321736
17331737
17341738
#include "appleboot.h"
#include "vers.h"
#include "edid.h"
#include "autoresolution.h"
#define THEME_NAME_DEFAULT"Default"
static const char *theme_name = THEME_NAME_DEFAULT;
int initGUI(void)
{
int val;
int val, count;
#ifdef EMBED_THEME
config_file_t*config;
#else
intlen;
chardirspec[256];
// find theme name in boot.plist
getValueForKey( "Theme", &theme_name, &len, &bootInfo->bootConfig );
if ((strlen(theme_name) + 27) > sizeof(dirspec)) {
return 1;
return 1;
}
#endif
// parse display size parameters
if (autoResolution == TRUE) {
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
mode_n = getVESAModeWithProperties( screen_params[0], screen_params[1], 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
/*
* AutoResolution
*/
if (autoResolution == TRUE) {//Get Resolution from Graphics Mode key
count = getNumberArrayFromProperty(kGraphicsModeKey, screen_params, 4);
if ( count < 3 ) {
//If no Graphics Mode key, get it from EDID
getResolution(&screen_params[0], &screen_params[1], &screen_params[2]);
}
} else {
// parse screen size parameters
if(getIntForKey("screen_width", &val, &bootInfo->themeConfig))
dprintf( &gui.screen, "name %s\n", param->name );
dprintf( &gui.screen, "type_name %s\n", param->type_name );
dprintf( &gui.screen, "modtime %d\n", param->modTime );
dprintf(&gui.screen, "width %d\n", gui.screen.width);
dprintf(&gui.screen, "height %d\n", gui.screen.height);
dprintf(&gui.screen, "attr: 0x%x\n", gui.screen.attr);
dprintf(&gui.screen, "mm: %d\n", gui.screen.mm);
#endif
}
void drawBootGraphics(void)
{
int pos;
int length;
int length, count;
const char *dummyVal;
bool legacy_logo;
uint16_t x, y;
loadBootGraphics();
}
if (autoResolution == TRUE) {
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
mode_n = getVESAModeWithProperties( screen_params[0], screen_params[1], 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
} else {
/*
* AutoResolution
*/
if (autoResolution == TRUE) {
//Get Resolution from Graphics Mode key
count = getNumberArrayFromProperty(kGraphicsModeKey, screen_params, 4);
if ( count < 3 ) {
//If no Graphics Mode key, get resolution from EDID
getResolution(&screen_params[0], &screen_params[1], &screen_params[2]);
}
} else {
// parse screen size parameters
if(getIntForKey("boot_width", &pos, &bootInfo->themeConfig))
screen_params[0] = pos;
branches/diebuche/i386/boot2/gui.h
9696
9797
9898
99
100
101
102
103
104
105
106
107
99108
100109
101110
uint32_tfont_small_color;// Color for small font AARRGGBB
uint32_tfont_console_color;// Color for consle font AARRGGBB
booldraw;// Draw flag
//resolution specifics
uint16_thtotal;
uint16_tvtotal;
uint16_thsyncstart;
uint16_thsyncend;
uint16_tvsyncstart;
uint16_tvsyncend;
uint8_tmm;
uint16_tattr;
} window_t;
/*

Archive Download the corresponding diff file

Revision: 132