e5fbd9a9012fa229a487f3c0bbbff32208cf6a1c
[eightysix] / kern / src / disp.c
1 #include "disp.h"
2 #include "asmutil.h"
3
4 static void detect_video(void);
5 static int detect_vgainfo(void);
6 static int detect_egainfo(void);
7 static void detect_eqlist(void);
8
9 struct console con_disp = { clear_disp, disp_putc, 0 };
10
11 static uint16_t __far *vmem;
12 static uint16_t cur_attr;
13 static int cur_x, cur_y;
14 static int cur_scroll;
15 static int mono;
16
17 void init_disp(void)
18 {
19         detect_video();
20 }
21
22 static void detect_video(void)
23 {
24         mono = 0;
25         disp_type = DISP_UNK;
26
27         if(detect_vgainfo() == 0) {
28                 goto done;
29         }
30         if(detect_egainfo() == 0) {
31                 goto done;
32         }
33         detect_eqlist();
34
35 done:
36         vmem = mono ? MK_FP(0xb000, 0) : MK_FP(0xb800, 0);
37 }
38
39 static int detect_vgainfo(void)
40 {
41         union regs regs;
42
43         regs.w.ax = 0x1a00;
44         int86(0x10, &regs, &regs);
45         if(regs.h.al != 0x1a) {
46                 return -1;
47         }
48
49         switch(regs.h.bl) {
50         case 1:
51                 disp_type = DISP_MDA;
52                 mono = 1;
53                 break;
54         case 2:
55                 disp_type = DISP_CGA;
56                 break;
57         case 4:
58                 disp_type = DISP_EGA;
59                 break;
60         case 5:
61                 disp_type = DISP_EGA;
62                 mono = 1;
63                 break;
64         case 6:
65                 disp_type = DISP_PGA;
66                 break;
67         case 7:
68                 disp_type = DISP_VGA;
69                 mono = 1;
70                 break;
71         case 8:
72                 disp_type = DISP_VGA;
73                 break;
74         case 0xa:
75         case 0xc:
76                 disp_type = DISP_MCGA;
77                 break;
78         case 0xb:
79                 disp_type = DISP_MCGA;
80                 mono = 1;
81                 break;
82         default:
83                 return -1;
84         }
85         return 0;
86 }
87
88 static int detect_egainfo(void)
89 {
90         union regs regs;
91
92         regs.w.ax = 0x1200;
93         regs.w.bx = 0xff10;
94         int86(0x10, &regs, &regs);
95         if(regs.h.bh == 0xff) {
96                 return -1;
97         }
98
99         disp_type = DISP_EGA;
100         mono = regs.h.bh;
101         return 0;
102 }
103
104 static void detect_eqlist(void)
105 {
106         union regs regs;
107
108         int86(0x11, &regs, &regs);
109         switch(regs.w.ax & 0x30) {
110         case 0:
111                 disp_type = DISP_EGA;
112                 break;
113
114         case 0x10:
115         case 0x20:
116                 disp_type = DISP_CGA;
117                 break;
118
119         case 0x30:
120                 disp_type = DISP_MDA;
121                 mono = 1;
122                 break;
123         }
124 }
125
126 void clear_disp(void)
127 {
128 }
129
130 void scroll_disp(int line)
131 {
132 }
133
134 void set_cursor(int x, int y)
135 {
136         cur_x = x;
137         cur_y = y;
138 }
139
140 void set_fgcolor(int color)
141 {
142         cur_attr = (cur_attr & 0xf0) | color;
143 }
144
145 void set_bgcolor(int color)
146 {
147         cur_attr = (cur_attr & 0x0f) | (color << 4);
148 }
149
150 void draw_glyph(int x, int y, int c, int attr)
151 {
152         vmem[y * 80 + x] = (uint16_t)c | ((uint16_t)attr << 8);
153 }
154
155 void draw_text(int x, int y, const char *s, int attr)
156 {
157         uint16_t __far *ptr = vmem + y * 80 + x;
158
159         while(*s) {
160                 *ptr++ = (uint16_t)*s++ | ((uint16_t)attr << 8);
161         }
162 }
163
164