1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <pc80/vga_io.h>
10 * pci io enable should've happened before
15 vga_enable_mask(0x01, 0x01);
17 /* cr io is at 0x3D4/0x3D5 */
18 vga_misc_mask(0x01, 0x01);
20 /* clear cr0-7 protection */
21 vga_cr_mask(0x11, 0x00, 0x80);
30 vga_sr_write(0x02, 0x03);
31 vga_sr_write(0x03, 0x00);
32 vga_sr_write(0x04, 0x02); /* access all 256kB */
34 vga_gr_write(0x00, 0x00);
35 vga_gr_write(0x01, 0x00);
36 vga_gr_write(0x02, 0x00);
37 vga_gr_write(0x03, 0x00);
38 vga_gr_write(0x04, 0x00);
39 vga_gr_write(0x05, 0x10);
40 vga_gr_write(0x06, 0x0E); /* map at 0xB8000 */
41 vga_gr_write(0x07, 0x00);
42 vga_gr_write(0x08, 0xFF);
44 /* o/e enable: RAM enable */
45 vga_misc_mask(0x22, 0x22);
54 memset((void *)VGA_FB
, 0x00, 0x8000);
61 vga_palette_init(void)
65 /* set up attribute registers */
66 for (i
= 0; i
< 0x10; i
++)
69 vga_ar_write(0x10, 0x0c);
70 vga_ar_write(0x11, 0x00);
71 vga_ar_write(0x12, 0x0F);
72 vga_ar_write(0x13, 0x08);
73 vga_ar_write(0x14, 0x00);
75 vga_palette_disable();
77 /* load actual palette */
78 vga_dac_mask_write(0xFF);
80 for (i
= 0; i
< 0x100; i
++) {
81 vga_dac_write_address(i
);
82 vga_dac_data_write(default_vga_palette
[i
].red
);
83 vga_dac_data_write(default_vga_palette
[i
].green
);
84 vga_dac_data_write(default_vga_palette
[i
].blue
);
92 vga_mode_set(int hdisplay
, int hblankstart
, int hsyncstart
, int hsyncend
,
93 int hblankend
, int htotal
, int vdisplay
, int vblankstart
,
94 int vsyncstart
, int vsyncend
, int vblankend
, int vtotal
,
100 vga_cr_write(0x00, htotal
);
105 vga_cr_write(0x01, hdisplay
);
107 /* hblankstart: 2048 */
110 vga_cr_write(0x02, hblankstart
);
112 /* hblankend: hblankstart + 512 */
115 vga_cr_mask(0x03, hblankend
, 0x1F);
116 vga_cr_mask(0x05, hblankend
<< 2, 0x80);
118 /* hsyncstart: 255 * 8: 2040 */
119 vga_cr_write(0x04, hsyncstart
/ 8);
121 /* hsyncend: hsyncstart + 255 */
122 vga_cr_mask(0x05, hsyncend
/ 8, 0x1F);
126 vga_cr_write(0x06, vtotal
);
127 vga_cr_mask(0x07, vtotal
>> 8, 0x01);
128 vga_cr_mask(0x07, vtotal
>> 4, 0x20);
132 vga_cr_write(0x12, vdisplay
);
133 vga_cr_mask(0x07, vdisplay
>> 7, 0x02);
134 vga_cr_mask(0x07, vdisplay
>> 3, 0x40);
136 /* vblankstart: 1024 */
138 vga_cr_write(0x15, vblankstart
);
139 vga_cr_mask(0x07, vblankstart
>> 5, 0x08);
140 vga_cr_mask(0x09, vblankstart
>> 4, 0x20);
142 /* vblankend: vblankstart + 256 */
144 vga_cr_write(0x16, vblankend
);
146 /* vsyncstart: 1023 */
147 vga_cr_write(0x10, vsyncstart
);
148 vga_cr_mask(0x07, vsyncstart
>> 6, 0x04);
149 vga_cr_mask(0x07, vsyncstart
>> 2, 0x80);
151 /* vsyncend: vsyncstart + 16 */
152 vga_cr_mask(0x11, vsyncend
, 0x0F);
155 vga_cr_write(0x13, stride
/ 8);
158 vga_cr_write(0x18, 0xFF);
159 vga_cr_mask(0x07, 0x10, 0x10);
160 vga_cr_mask(0x09, 0x40, 0x40);
162 vga_misc_mask(0x44, 0xCC); /* set up clock: 27mhz and h/vsync */
164 vga_cr_mask(0x09, 0x00, 0x80); /* disable doublescan */
168 vga_font_8x16_load(void)
172 unsigned char sr2
, sr4
, gr5
, gr6
;
177 sr2
= vga_sr_read(0x02);
178 sr4
= vga_sr_read(0x04);
179 gr5
= vga_gr_read(0x05);
180 gr6
= vga_gr_read(0x06);
182 /* disable odd/even */
183 vga_sr_mask(0x04, 0x04, 0x04);
184 vga_gr_mask(0x05, 0x00, 0x10);
185 vga_gr_mask(0x06, 0x00, 0x02);
188 vga_sr_write(0x02, 0x04);
189 p
= (unsigned char *)VGA_FB
;
190 for (i
= 0; i
< count
; i
++) {
191 for (j
= 0; j
< 32; j
++) {
193 *p
= vga_font_8x16
[i
][j
];
200 vga_gr_write(0x06, gr6
);
201 vga_gr_write(0x05, gr5
);
202 vga_sr_write(0x04, sr4
);
203 vga_sr_write(0x02, sr2
);
205 /* set up font size */
206 vga_cr_mask(0x09, 16 - 1, 0x1F);
213 vga_cursor_enable(int enable
)
216 vga_cr_mask(0x0A, 0x00, 0x20);
218 vga_cr_mask(0x0A, 0x20, 0x20);
225 vga_cursor_reset(void)
227 vga_cr_write(0x0A, 0x2E);
228 vga_cr_write(0x0B, 0x0E);
229 vga_cr_write(0x0E, 0x00);
230 vga_cr_write(0x0F, 0x00);
237 vga_cursor_set(unsigned int line
, unsigned int character
)
239 unsigned int offset
= (VGA_COLUMNS
* line
+ character
) & 0xFFFF;
241 vga_cr_write(0x0A, 0x0E);
242 vga_cr_write(0x0B, 0x0E);
243 vga_cr_write(0x0E, offset
>> 8);
244 vga_cr_write(0x0F, offset
& 0xFF);
251 vga_frame_set(unsigned int line
, unsigned int character
)
253 unsigned int offset
= (VGA_COLUMNS
* line
+ character
) & 0xFFFF;
255 vga_cr_write(0x0C, offset
>> 8);
256 vga_cr_write(0x0D, offset
& 0xFF);
260 vga_write_at_offset(unsigned int line
, unsigned int offset
, const char *string
)
265 unsigned short *p
= (unsigned short *)VGA_FB
+ (VGA_COLUMNS
* line
) + offset
;
266 size_t i
, len
= strlen(string
);
268 for (i
= 0; i
< (VGA_COLUMNS
- offset
); i
++) {
270 p
[i
] = 0x0F00 | (unsigned char)string
[i
];
277 * simply fills a line with the given string.
280 vga_line_write(unsigned int line
, const char *string
)
282 vga_write_at_offset(line
, 0, string
);
286 vga_write_text(enum VGA_TEXT_ALIGNMENT alignment
, unsigned int line
, const char *string
)
288 char str
[VGA_COLUMNS
* VGA_LINES
] = {0};
289 memcpy(str
, string
, strnlen(string
, sizeof(str
) - 1));
291 char *token
= strtok(str
, "\n");
293 while (token
!= NULL
) {
294 size_t offset
= VGA_COLUMNS
- strnlen(token
, VGA_COLUMNS
);
296 case VGA_TEXT_CENTER
:
297 vga_write_at_offset(line
++, offset
/2, token
);
300 vga_write_at_offset(line
++, offset
, token
);
304 vga_write_at_offset(line
++, 0, token
);
307 token
= strtok(NULL
, "\n");
312 * set up everything to get a basic 80x25 textmode.
315 vga_textmode_init(void)
317 vga_sr_write(0x00, 0x01); /* clear reset */
318 vga_sr_write(0x01, 0x00);
321 vga_cr_mask(0x03, 0x80, 0xE0);
322 vga_cr_mask(0x05, 0x00, 0x60);
324 vga_cr_write(0x08, 0x00);
326 vga_cr_write(0x14, 0x00); /* */
328 vga_cr_write(0x17, 0x23);
332 vga_mode_set(640, 648, 680, 776, 792, 800,
333 400, 407, 412, 414, 442, 449, 320);
340 vga_font_8x16_load();
342 vga_sr_mask(0x00, 0x02, 0x02); /* take us out of reset */
343 vga_cr_mask(0x17, 0x80, 0x80); /* sync! */