1 /* ----------------------------------------------------------------------- *
3 * Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 * Copyright 2013 Intel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 * Boston MA 02111-1307, USA; either version 2 of the License, or
10 * (at your option) any later version; incorporated herein by reference.
12 * ----------------------------------------------------------------------- */
18 * VGA font handling code
22 #include <syslinux/firmware.h>
23 #include <syslinux/video.h>
32 __export
uint8_t UserFont
= 0; /* Using a user-specified font */
34 __export __lowmem
char fontbuf
[8192];
36 uint16_t GXPixCols
= 1; /* Graphics mode pixel columns */
37 uint16_t GXPixRows
= 1; /* Graphics mode pixel rows */
40 * loadfont: Load a .psf font file and install it onto the VGA console
41 * (if we're not on a VGA screen then ignore.)
43 __export
void loadfont(const char *filename
)
52 f
= fopen(filename
, "r");
57 if (_fread(&hdr
, sizeof hdr
, f
) != sizeof hdr
)
61 if (hdr
.magic
!= 0x0436)
64 /* File mode: font modes 0-5 supported */
68 /* VGA minimum/maximum */
69 if (hdr
.height
< 2 || hdr
.height
> 32)
72 /* Load the actual font into the font buffer. */
73 memset(fontbuf
, 0, 256*32);
74 if (_fread(fontbuf
, 256*hdr
.height
, f
) != 256*hdr
.height
)
78 VGAFontSize
= hdr
.height
;
79 UserFont
= 1; /* Set font flag */
88 * This routine activates whatever font happens to be in the
89 * vgafontbuf, and updates the bios_adjust_screen data.
90 * Must be called with CS = DS
94 com32sys_t ireg
, oreg
;
95 uint8_t bytes
= VGAFontSize
;
97 /* Nonstandard mode? */
99 syslinux_force_text_mode();
101 memset(&ireg
, 0, sizeof(ireg
));
103 ireg
.es
= SEG(fontbuf
);
104 ireg
.ebp
.w
[0] = OFFS(fontbuf
); /* ES:BP -> font */
106 /* Are we using a user-specified font? */
107 if (UserFont
& 0x1) {
108 /* Are we in graphics mode? */
109 if (UsingVGA
& 0x1) {
112 rows
= GXPixRows
/ bytes
;
115 /* Set user character table */
116 ireg
.eax
.w
[0] = 0x1121;
118 ireg
.ecx
.b
[0] = bytes
; /* bytes/character */
119 ireg
.edx
.b
[0] = rows
;
121 __intcall(0x10, &ireg
, &oreg
);
123 /* 8 pixels/character */
124 VidCols
= ((GXPixCols
>> 3) - 1);
126 /* No need to call bios_adjust_screen */
129 ireg
.eax
.w
[0] = 0x1110; /* Load into VGA RAM */
131 ireg
.ebx
.b
[1] = bytes
; /* bytes/character */
135 __intcall(0x10, &ireg
, &oreg
);
137 memset(&ireg
, 0, sizeof(ireg
));
139 ireg
.eax
.w
[0] = 0x1103; /* Select page 0 */
140 __intcall(0x10, &ireg
, NULL
);
145 bios_adjust_screen();
149 * bios_adjust_screen: Set the internal variables associated with the screen size.
150 * This is a subroutine in case we're loading a custom font.
152 void bios_adjust_screen(void)
154 com32sys_t ireg
, oreg
;
155 volatile uint8_t *vidrows
= (volatile uint8_t *)BIOS_vidrows
;
158 memset(&ireg
, 0, sizeof(ireg
));
163 * No vidrows in BIOS, assume 25.
164 * (Remember: vidrows == rows-1)
171 ireg
.eax
.b
[1] = 0x0f; /* Read video state */
172 __intcall(0x10, &ireg
, &oreg
);
173 cols
= oreg
.eax
.b
[1];
175 VidCols
= --cols
; /* Store count-1 (same as rows) */
178 void adjust_screen(void)
180 if (firmware
->adjust_screen
)
181 firmware
->adjust_screen();
184 void pm_adjust_screen(com32sys_t
*regs __unused
)
189 void pm_userfont(com32sys_t
*regs
)
191 regs
->es
= SEG(fontbuf
);
192 regs
->ebx
.w
[0] = OFFS(fontbuf
);