The getControllerInfo and getModeInfo calls were working properly only if the argumen...
[tangerine.git] / arch / x86_64-pc / bootstrap / vesa.c
blob745cb098320c88827246f4af9ca2b02dc4bc21da
1 #define _IMPLEMENTATION_
3 asm ("begin:");
5 #include "vesa.h"
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)
17 while (size--)
18 *to++ = *from++;
21 short getControllerInfo(struct vbe_controller *info)
23 short retval;
24 asm volatile("call go16 \n\t.code16 \n\t"
25 "movw $0x4f00, %%ax\n\t"
26 "int $0x10\n\t"
27 "movw %%ax, %0\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));
30 return retval;
33 short getModeInfo(long mode, struct vbe_mode *info)
35 short retval;
36 asm volatile("call go16 \n\t.code16 \n\t"
37 "movw $0x4f01, %%ax\n\t"
38 "int $0x10\n\t"
39 "movw %%ax, %0\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));
42 return retval;
45 short setVbeMode(long mode)
47 short retval;
48 asm volatile("call go16 \n\t.code16 \n\t"
49 "movw $0x4f02, %%ax\n\t"
50 "int $0x10\n\t"
51 "movw %%ax, %0\n\t"
52 "DATA32 call go32\n\t.code32\n\t":"=b"(retval):"0"(mode & 0xf7ff):"eax","ecx","cc");
53 return retval;
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));
67 int i;
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)
78 return modes[i];
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))
84 bestmode = modes[i];
85 bestmatch = match;
86 bestmatchd = matchd;
90 return bestmode;
93 asm(
94 " .code16\n\t.globl go32\n\t.type go32,@function\n"
95 "go32: DATA32 ADDR32 lgdt GDT_reg\n"
96 " movl %cr0, %eax\n"
97 " bts $0, %eax\n"
98 " movl %eax, %cr0\n"
99 " ljmp $0x08, $1f\n"
100 " .code32\n"
101 "1: movw $0x10, %ax\n"
102 " movw %ax, %ds\n"
103 " movw %ax, %es\n"
104 " movw %ax, %fs\n"
105 " movw %ax, %gs\n"
106 " movw %ax, %ss\n"
107 " movl (%esp), %ecx\n"
108 " movl stack32, %eax\n"
109 " movl %eax, %esp\n"
110 " movl %eax, %ebp\n"
111 " movl %ecx, (%esp)\n"
112 " xorl %eax, %eax\n"
113 " ret\n"
114 "\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"
121 " movl %esp, %ebp\n"
122 " movw $0x20, %ax\n"
123 " movw %ax, %ds\n"
124 " movw %ax, %es\n"
125 " movw %ax, %fs\n"
126 " movw %ax, %gs\n"
127 " movw %ax, %ss\n"
128 " ljmp $0x18, $1f\n\t.code16\n"
129 "1:\n"
130 " movl %cr0, %eax\n"
131 " btc $0, %eax\n"
132 " movl %eax, %cr0\n"
133 " DATA32 ljmp $0x00, $1f\n"
134 "1:\n"
135 " xorl %eax,%eax\n"
136 " movw %ax, %ds\n"
137 " movw %ax, %es\n"
138 " movw %ax, %fs\n"
139 " movw %ax, %gs\n"
140 " movw %ax, %ss\n"
141 " DATA32 ret\n"
142 ".code32");
144 const unsigned long long GDT_Table[] = {
145 0x0000000000000000ULL,
146 0x00cf9a000000ffffULL, /* Code32 */
147 0x00cf92000000ffffULL, /* Data32 */
148 0x00009e000000ffffULL, /* Code16 */
149 0x000092000000ffffULL /* Data16 */
152 const struct
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;