1 #define _IMPLEMENTATION_
6 #define ABS(x) (((x) >= 0) ? (x) : -(x))
8 asm (".long getControllerInfo");
9 asm (".long getModeInfo");
10 asm (".long findMode");
11 asm (".long setVbeMode");
12 asm (".long paletteWidth");
13 asm (".long controllerinfo");
14 asm (".long modeinfo");
16 short getControllerInfo(void)
19 asm volatile("call go16 \n\t.code16 \n\t"
20 "movw $0x4f00, %%ax\n\t"
23 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"D"(&controllerinfo
):"eax","ecx","cc");
27 /* In VBE 1.1 information about standard modes was optional,
28 so we use a hardcoded table here (we rely on this information) */
29 struct vesa11Info vesa11Modes
[] = {
40 short getModeInfo(long mode
)
44 char *ptr
= (char *)&modeinfo
;
45 for (i
= 0; i
< sizeof(modeinfo
); i
++)
47 asm volatile("call go16 \n\t.code16 \n\t"
48 "movw $0x4f01, %%ax\n\t"
51 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"c"(mode
),"D"(&modeinfo
):"eax","cc");
52 if ((controllerinfo
.version
< 0x0102) && (mode
> 0x0FF) && (mode
< 0x108)) {
54 modeinfo
.x_resolution
= vesa11Modes
[i
].x_resolution
;
55 modeinfo
.y_resolution
= vesa11Modes
[i
].y_resolution
;
56 modeinfo
.bits_per_pixel
= vesa11Modes
[i
].bits_per_pixel
;
57 modeinfo
.memory_model
= vesa11Modes
[i
].memory_model
;
62 short setVbeMode(long mode
)
65 asm volatile("call go16 \n\t.code16 \n\t"
66 "movw $0x4f02, %%ax\n\t"
69 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"0"(mode
& 0xf7ff):"eax","ecx","cc");
73 short paletteWidth(long req
, unsigned char* width
)
76 unsigned char reswidth
;
78 asm volatile("call go16\n\t.code16\n\t"
79 "movw $0x4f08, %%ax\n\t"
83 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
),"=c"(reswidth
):"0"(req
):"eax","cc");
88 short findMode(int x
, int y
, int d
)
90 unsigned long match
, bestmatch
= ABS(640*480 - x
*y
);
91 unsigned long matchd
, bestmatchd
= 15 >= d
? 15 - d
: (d
- 15) * 2;
92 unsigned short bestmode
= 0x110;
93 unsigned short mode_attrs
;
95 if (getControllerInfo() == 0x4f)
97 unsigned short *modes
= (unsigned short *)
98 (((controllerinfo
.video_mode
& 0xffff0000) >> 12) + (controllerinfo
.video_mode
& 0xffff));
102 if (controllerinfo
.version
< 0x0200)
107 for (i
=0; modes
[i
] != 0xffff; ++i
)
109 if (getModeInfo(modes
[i
])!= 0x4f) continue;
110 if ((modeinfo
.mode_attributes
& mode_attrs
) != mode_attrs
) continue;
111 if ((modeinfo
.memory_model
!= 6) && (modeinfo
.memory_model
!= 4))
113 if ((modeinfo
.memory_model
== 4) && (modeinfo
.mode_attributes
& 0x20))
116 if (modeinfo
.x_resolution
== x
&&
117 modeinfo
.y_resolution
== y
&&
118 modeinfo
.bits_per_pixel
== d
)
121 match
= ABS(modeinfo
.x_resolution
*modeinfo
.y_resolution
- x
*y
);
122 matchd
= modeinfo
.bits_per_pixel
>= d
? modeinfo
.bits_per_pixel
-d
: (d
-modeinfo
.bits_per_pixel
)*2;
123 if (match
< bestmatch
|| (match
== bestmatch
&& matchd
< bestmatchd
))
135 " .code16\n\t.globl go32\n\t.type go32,@function\n"
136 "go32: DATA32 ADDR32 lgdt GDT_reg\n"
142 "1: movw $0x10, %ax\n"
148 " movl (%esp), %ecx\n"
149 " movl stack32, %eax\n"
151 " movl %ecx, (%esp)\n"
155 " .code32\n\t.globl go16\n\t.type go16,@function\n"
156 "go16: lgdt GDT_reg\n"
157 " movl %esp, stack32\n"
158 " movl (%esp), %eax\n"
159 " movl %eax, begin + 0xff8\n"
160 " movl $begin + 0xff8, %esp\n"
167 " ljmp $0x18, $1f\n\t.code16\n"
172 " DATA32 ljmp $0x00, $1f\n"
183 const unsigned long long GDT_Table
[] = {
184 0x0000000000000000ULL
,
185 0x00cf9a000000ffffULL
, /* Code32 */
186 0x00cf92000000ffffULL
, /* Data32 */
187 0x00009e000000ffffULL
, /* Code16 */
188 0x000092000000ffffULL
/* Data16 */
193 unsigned short l1
__attribute__((packed
));
194 const void *l3
__attribute__((packed
));
196 GDT_reg
= {sizeof(GDT_Table
)-1, GDT_Table
};
198 unsigned long stack32
;
199 struct vbe_controller controllerinfo
;
200 struct vbe_mode modeinfo
;