Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / i386-pc / exec / vesa.c
blobe9c316a70a3468c923fccbe412ca74aab2d928eb
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 paletteWidth");
13 asm (".long controllerinfo");
14 asm (".long modeinfo");
16 short getControllerInfo(void)
18 short retval;
19 asm volatile("call go16 \n\t.code16 \n\t"
20 "movw $0x4f00, %%ax\n\t"
21 "int $0x10\n\t"
22 "movw %%ax, %0\n\t"
23 "DATA32 call go32\n\t.code32\n\t":"=b"(retval):"D"(&controllerinfo):"eax","ecx","cc");
24 return retval;
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[] = {
30 {640, 400, 8, 4},
31 {640, 480, 8, 4},
32 {800, 600, 4, 3},
33 {800, 600, 8, 4},
34 {1024, 768, 4, 3},
35 {1024, 768, 8, 4},
36 {1280, 1024, 4, 3},
37 {1280, 1024, 8, 4}
40 short getModeInfo(long mode)
42 short retval;
43 long i;
44 char *ptr = (char *)&modeinfo;
45 for (i = 0; i < sizeof(modeinfo); i++)
46 *ptr++ = 0;
47 asm volatile("call go16 \n\t.code16 \n\t"
48 "movw $0x4f01, %%ax\n\t"
49 "int $0x10\n\t"
50 "movw %%ax, %0\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)) {
53 i = mode - 0x100;
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;
59 return retval;
62 short setVbeMode(long mode)
64 short retval;
65 asm volatile("call go16 \n\t.code16 \n\t"
66 "movw $0x4f02, %%ax\n\t"
67 "int $0x10\n\t"
68 "movw %%ax, %0\n\t"
69 "DATA32 call go32\n\t.code32\n\t":"=b"(retval):"0"(mode & 0xf7ff):"eax","ecx","cc");
70 return retval;
73 short paletteWidth(long req, unsigned char* width)
75 short retval;
76 unsigned char reswidth;
78 asm volatile("call go16\n\t.code16\n\t"
79 "movw $0x4f08, %%ax\n\t"
80 "int $0x10\n\t"
81 "movb %%bh, %1\n\t"
82 "movw %%ax, %0\n\t"
83 "DATA32 call go32\n\t.code32\n\t":"=b"(retval),"=c"(reswidth):"0"(req):"eax","cc");
84 *width = reswidth;
85 return retval;
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));
100 int i;
102 if (controllerinfo.version < 0x0200)
103 mode_attrs = 0x11;
104 else
105 mode_attrs = 0x91;
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))
112 continue;
113 if ((modeinfo.memory_model == 4) && (modeinfo.mode_attributes & 0x20))
114 continue;
116 if (modeinfo.x_resolution == x &&
117 modeinfo.y_resolution == y &&
118 modeinfo.bits_per_pixel == d)
119 return modes[i];
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))
125 bestmode = modes[i];
126 bestmatch = match;
127 bestmatchd = matchd;
131 return bestmode;
134 asm(
135 " .code16\n\t.globl go32\n\t.type go32,@function\n"
136 "go32: DATA32 ADDR32 lgdt GDT_reg\n"
137 " movl %cr0, %eax\n"
138 " bts $0, %eax\n"
139 " movl %eax, %cr0\n"
140 " ljmp $0x08, $1f\n"
141 " .code32\n"
142 "1: movw $0x10, %ax\n"
143 " movw %ax, %ds\n"
144 " movw %ax, %es\n"
145 " movw %ax, %fs\n"
146 " movw %ax, %gs\n"
147 " movw %ax, %ss\n"
148 " movl (%esp), %ecx\n"
149 " movl stack32, %eax\n"
150 " movl %eax, %esp\n"
151 " movl %ecx, (%esp)\n"
152 " xorl %eax, %eax\n"
153 " ret\n"
154 "\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"
161 " movw $0x20, %ax\n"
162 " movw %ax, %ds\n"
163 " movw %ax, %es\n"
164 " movw %ax, %fs\n"
165 " movw %ax, %gs\n"
166 " movw %ax, %ss\n"
167 " ljmp $0x18, $1f\n\t.code16\n"
168 "1:\n"
169 " movl %cr0, %eax\n"
170 " btc $0, %eax\n"
171 " movl %eax, %cr0\n"
172 " DATA32 ljmp $0x00, $1f\n"
173 "1:\n"
174 " xorl %eax,%eax\n"
175 " movw %ax, %ds\n"
176 " movw %ax, %es\n"
177 " movw %ax, %fs\n"
178 " movw %ax, %gs\n"
179 " movw %ax, %ss\n"
180 " DATA32 ret\n"
181 ".code32");
183 const unsigned long long GDT_Table[] = {
184 0x0000000000000000ULL,
185 0x00cf9a000000ffffULL, /* Code32 */
186 0x00cf92000000ffffULL, /* Data32 */
187 0x00009e000000ffffULL, /* Code16 */
188 0x000092000000ffffULL /* Data16 */
191 const struct
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;