0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "boot.h"
0015 #include "video.h"
0016
0017 static struct mode_info vga_modes[] = {
0018 { VIDEO_80x25, 80, 25, 0 },
0019 { VIDEO_8POINT, 80, 50, 0 },
0020 { VIDEO_80x43, 80, 43, 0 },
0021 { VIDEO_80x28, 80, 28, 0 },
0022 { VIDEO_80x30, 80, 30, 0 },
0023 { VIDEO_80x34, 80, 34, 0 },
0024 { VIDEO_80x60, 80, 60, 0 },
0025 };
0026
0027 static struct mode_info ega_modes[] = {
0028 { VIDEO_80x25, 80, 25, 0 },
0029 { VIDEO_8POINT, 80, 43, 0 },
0030 };
0031
0032 static struct mode_info cga_modes[] = {
0033 { VIDEO_80x25, 80, 25, 0 },
0034 };
0035
0036 static __videocard video_vga;
0037
0038
0039 static u8 vga_set_basic_mode(void)
0040 {
0041 struct biosregs ireg, oreg;
0042 u8 mode;
0043
0044 initregs(&ireg);
0045
0046
0047 ireg.ax = 0x0f00;
0048 intcall(0x10, &ireg, &oreg);
0049 mode = oreg.al;
0050
0051 if (mode != 3 && mode != 7)
0052 mode = 3;
0053
0054
0055 ireg.ax = mode;
0056 intcall(0x10, &ireg, NULL);
0057 do_restore = 1;
0058 return mode;
0059 }
0060
0061 static void vga_set_8font(void)
0062 {
0063
0064 struct biosregs ireg;
0065
0066 initregs(&ireg);
0067
0068
0069 ireg.ax = 0x1112;
0070
0071 intcall(0x10, &ireg, NULL);
0072
0073
0074 ireg.ax = 0x1200;
0075 ireg.bl = 0x20;
0076 intcall(0x10, &ireg, NULL);
0077
0078
0079 ireg.ax = 0x1201;
0080 ireg.bl = 0x34;
0081 intcall(0x10, &ireg, NULL);
0082
0083
0084 ireg.ax = 0x0100;
0085 ireg.cx = 0x0607;
0086 intcall(0x10, &ireg, NULL);
0087 }
0088
0089 static void vga_set_14font(void)
0090 {
0091
0092 struct biosregs ireg;
0093
0094 initregs(&ireg);
0095
0096
0097 ireg.ax = 0x1111;
0098
0099 intcall(0x10, &ireg, NULL);
0100
0101
0102 ireg.ax = 0x1201;
0103 ireg.bl = 0x34;
0104 intcall(0x10, &ireg, NULL);
0105
0106
0107 ireg.ax = 0x0100;
0108 ireg.cx = 0x0b0c;
0109 intcall(0x10, &ireg, NULL);
0110 }
0111
0112 static void vga_set_80x43(void)
0113 {
0114
0115 struct biosregs ireg;
0116
0117 initregs(&ireg);
0118
0119
0120 ireg.ax = 0x1201;
0121 ireg.bl = 0x30;
0122 intcall(0x10, &ireg, NULL);
0123
0124
0125 ireg.ax = 0x0003;
0126 intcall(0x10, &ireg, NULL);
0127
0128 vga_set_8font();
0129 }
0130
0131
0132 u16 vga_crtc(void)
0133 {
0134 return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
0135 }
0136
0137 static void vga_set_480_scanlines(void)
0138 {
0139 u16 crtc;
0140 u8 csel;
0141
0142 crtc = vga_crtc();
0143
0144 out_idx(0x0c, crtc, 0x11);
0145 out_idx(0x0b, crtc, 0x06);
0146 out_idx(0x3e, crtc, 0x07);
0147 out_idx(0xea, crtc, 0x10);
0148 out_idx(0xdf, crtc, 0x12);
0149 out_idx(0xe7, crtc, 0x15);
0150 out_idx(0x04, crtc, 0x16);
0151 csel = inb(0x3cc);
0152 csel &= 0x0d;
0153 csel |= 0xe2;
0154 outb(csel, 0x3c2);
0155 }
0156
0157 static void vga_set_vertical_end(int lines)
0158 {
0159 u16 crtc;
0160 u8 ovfw;
0161 int end = lines-1;
0162
0163 crtc = vga_crtc();
0164
0165 ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
0166
0167 out_idx(ovfw, crtc, 0x07);
0168 out_idx(end, crtc, 0x12);
0169 }
0170
0171 static void vga_set_80x30(void)
0172 {
0173 vga_set_480_scanlines();
0174 vga_set_vertical_end(30*16);
0175 }
0176
0177 static void vga_set_80x34(void)
0178 {
0179 vga_set_480_scanlines();
0180 vga_set_14font();
0181 vga_set_vertical_end(34*14);
0182 }
0183
0184 static void vga_set_80x60(void)
0185 {
0186 vga_set_480_scanlines();
0187 vga_set_8font();
0188 vga_set_vertical_end(60*8);
0189 }
0190
0191 static int vga_set_mode(struct mode_info *mode)
0192 {
0193
0194 vga_set_basic_mode();
0195
0196
0197 force_x = mode->x;
0198 force_y = mode->y;
0199
0200 switch (mode->mode) {
0201 case VIDEO_80x25:
0202 break;
0203 case VIDEO_8POINT:
0204 vga_set_8font();
0205 break;
0206 case VIDEO_80x43:
0207 vga_set_80x43();
0208 break;
0209 case VIDEO_80x28:
0210 vga_set_14font();
0211 break;
0212 case VIDEO_80x30:
0213 vga_set_80x30();
0214 break;
0215 case VIDEO_80x34:
0216 vga_set_80x34();
0217 break;
0218 case VIDEO_80x60:
0219 vga_set_80x60();
0220 break;
0221 }
0222
0223 return 0;
0224 }
0225
0226
0227
0228
0229
0230
0231 static int vga_probe(void)
0232 {
0233 static const char *card_name[] = {
0234 "CGA/MDA/HGC", "EGA", "VGA"
0235 };
0236 static struct mode_info *mode_lists[] = {
0237 cga_modes,
0238 ega_modes,
0239 vga_modes,
0240 };
0241 static int mode_count[] = {
0242 ARRAY_SIZE(cga_modes),
0243 ARRAY_SIZE(ega_modes),
0244 ARRAY_SIZE(vga_modes),
0245 };
0246
0247 struct biosregs ireg, oreg;
0248
0249 initregs(&ireg);
0250
0251 ireg.ax = 0x1200;
0252 ireg.bl = 0x10;
0253 intcall(0x10, &ireg, &oreg);
0254
0255 #ifndef _WAKEUP
0256 boot_params.screen_info.orig_video_ega_bx = oreg.bx;
0257 #endif
0258
0259
0260 if (oreg.bl != 0x10) {
0261
0262 ireg.ax = 0x1a00;
0263 intcall(0x10, &ireg, &oreg);
0264
0265 if (oreg.al == 0x1a) {
0266 adapter = ADAPTER_VGA;
0267 #ifndef _WAKEUP
0268 boot_params.screen_info.orig_video_isVGA = 1;
0269 #endif
0270 } else {
0271 adapter = ADAPTER_EGA;
0272 }
0273 } else {
0274 adapter = ADAPTER_CGA;
0275 }
0276
0277 video_vga.modes = mode_lists[adapter];
0278 video_vga.card_name = card_name[adapter];
0279 return mode_count[adapter];
0280 }
0281
0282 static __videocard video_vga = {
0283 .card_name = "VGA",
0284 .probe = vga_probe,
0285 .set_mode = vga_set_mode,
0286 };