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 controllerinfo");
13 asm (".long modeinfo");
15 static void memcpy(char *from
, char *to
, int size
)
21 short getControllerInfo(struct vbe_controller
*info
)
24 asm volatile("call go16 \n\t.code16 \n\t"
25 "movw $0x4f00, %%ax\n\t"
28 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"D"(&controllerinfo
):"eax","ecx","cc");
29 memcpy(&controllerinfo
, info
, sizeof(struct vbe_controller
));
33 short getModeInfo(long mode
, struct vbe_mode
*info
)
36 asm volatile("call go16 \n\t.code16 \n\t"
37 "movw $0x4f01, %%ax\n\t"
40 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"c"(mode
),"D"(&modeinfo
):"eax","cc");
41 memcpy(&modeinfo
, info
, sizeof(struct vbe_mode
));
45 short setVbeMode(long mode
)
48 asm volatile("call go16 \n\t.code16 \n\t"
49 "movw $0x4f02, %%ax\n\t"
52 "DATA32 call go32\n\t.code32\n\t":"=b"(retval
):"0"(mode
& 0xf7ff):"eax","ecx","cc");
56 short findMode(int x
, int y
, int d
)
58 unsigned long match
, bestmatch
= ABS(640*480 - x
*y
);
59 unsigned long matchd
, bestmatchd
= 15 >= d
? 15 - d
: (d
- 15) * 2;
60 unsigned short bestmode
= 0x110;
62 if (getControllerInfo(&controllerinfo
) == 0x4f)
64 unsigned short *modes
= (unsigned short *)
65 (((controllerinfo
.video_mode
& 0xffff0000) >> 12) + (controllerinfo
.video_mode
& 0xffff));
69 for (i
=0; modes
[i
] != 0xffff; ++i
)
71 if (getModeInfo(modes
[i
], &modeinfo
)!= 0x4f) continue;
72 if ((modeinfo
.mode_attributes
& 0x90) != 0x90) continue;
73 if (modeinfo
.memory_model
!= 6) continue;
75 if (modeinfo
.x_resolution
== x
&&
76 modeinfo
.y_resolution
== y
&&
77 modeinfo
.bits_per_pixel
== d
)
80 match
= ABS(modeinfo
.x_resolution
*modeinfo
.y_resolution
- x
*y
);
81 matchd
= modeinfo
.bits_per_pixel
>= d
? modeinfo
.bits_per_pixel
-d
: (d
-modeinfo
.bits_per_pixel
)*2;
82 if (match
< bestmatch
|| (match
== bestmatch
&& matchd
< bestmatchd
))
94 " .code16\n\t.globl go32\n\t.type go32,@function\n"
95 "go32: DATA32 ADDR32 lgdt GDT_reg\n"
101 "1: movw $0x10, %ax\n"
107 " movl (%esp), %ecx\n"
108 " movl stack32, %eax\n"
111 " movl %ecx, (%esp)\n"
115 " .code32\n\t.globl go16\n\t.type go16,@function\n"
116 "go16: lgdt GDT_reg\n"
117 " movl %esp, stack32\n"
118 " movl (%esp), %eax\n"
119 " movl %eax, begin + 0xff8\n"
120 " movl $begin + 0xff8, %esp\n"
128 " ljmp $0x18, $1f\n\t.code16\n"
133 " DATA32 ljmp $0x00, $1f\n"
144 const unsigned long long GDT_Table
[] = {
145 0x0000000000000000ULL
,
146 0x00cf9a000000ffffULL
, /* Code32 */
147 0x00cf92000000ffffULL
, /* Data32 */
148 0x00009e000000ffffULL
, /* Code16 */
149 0x000092000000ffffULL
/* Data16 */
154 unsigned short l1
__attribute__((packed
));
155 const void *l3
__attribute__((packed
));
157 GDT_reg
= {sizeof(GDT_Table
)-1, GDT_Table
};
159 unsigned long stack32
;
160 struct vbe_controller controllerinfo
;
161 struct vbe_mode modeinfo
;