Adding upstream version 6.00+dfgs.
[syslinux-debian/hramrach.git] / core / font.c
blob30c0afb884f0008d8df840f34b8207e1f9c35ec8
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 * ----------------------------------------------------------------------- */
16 * font.c
18 * VGA font handling code
22 #include <syslinux/firmware.h>
23 #include <sys/io.h>
24 #include <stdio.h>
25 #include <fs.h>
27 #include "bios.h"
28 #include "graphics.h"
29 #include "core.h"
31 __export uint8_t UserFont = 0; /* Using a user-specified font */
33 __export __lowmem char fontbuf[8192];
35 uint16_t GXPixCols = 1; /* Graphics mode pixel columns */
36 uint16_t GXPixRows = 1; /* Graphics mode pixel rows */
39 * loadfont: Load a .psf font file and install it onto the VGA console
40 * (if we're not on a VGA screen then ignore.)
42 __export void loadfont(const char *filename)
44 struct psfheader {
45 uint16_t magic;
46 uint8_t mode;
47 uint8_t height;
48 } hdr;
49 FILE *f;
51 f = fopen(filename, "r");
52 if (!f)
53 return;
55 /* Read header */
56 if (_fread(&hdr, sizeof hdr, f) != sizeof hdr)
57 goto fail;
59 /* Magic number */
60 if (hdr.magic != 0x0436)
61 goto fail;
63 /* File mode: font modes 0-5 supported */
64 if (hdr.mode > 5)
65 goto fail;
67 /* VGA minimum/maximum */
68 if (hdr.height < 2 || hdr.height > 32)
69 goto fail;
71 /* Load the actual font into the font buffer. */
72 memset(fontbuf, 0, 256*32);
73 if (_fread(fontbuf, 256*hdr.height, f) != 256*hdr.height)
74 goto fail;
76 /* Loaded OK */
77 VGAFontSize = hdr.height;
78 UserFont = 1; /* Set font flag */
79 use_font();
81 fail:
82 fclose(f);
86 * use_font:
87 * This routine activates whatever font happens to be in the
88 * vgafontbuf, and updates the bios_adjust_screen data.
89 * Must be called with CS = DS
91 void use_font(void)
93 com32sys_t ireg, oreg;
94 uint8_t bytes = VGAFontSize;
96 /* Nonstandard mode? */
97 if (UsingVGA & ~0x3)
98 syslinux_force_text_mode();
100 memset(&ireg, 0, sizeof(ireg));
102 ireg.es = SEG(fontbuf);
103 ireg.ebp.w[0] = OFFS(fontbuf); /* ES:BP -> font */
105 /* Are we using a user-specified font? */
106 if (UserFont & 0x1) {
107 /* Are we in graphics mode? */
108 if (UsingVGA & 0x1) {
109 uint8_t rows;
111 rows = GXPixRows / bytes;
112 VidRows = rows - 1;
114 /* Set user character table */
115 ireg.eax.w[0] = 0x1121;
116 ireg.ebx.b[0] = 0;
117 ireg.ecx.b[0] = bytes; /* bytes/character */
118 ireg.edx.b[0] = rows;
120 __intcall(0x10, &ireg, &oreg);
122 /* 8 pixels/character */
123 VidCols = ((GXPixCols >> 3) - 1);
125 /* No need to call bios_adjust_screen */
126 return;
127 } else {
128 ireg.eax.w[0] = 0x1110; /* Load into VGA RAM */
129 ireg.ebx.b[0] = 0;
130 ireg.ebx.b[1] = bytes; /* bytes/character */
131 ireg.ecx.w[0] = 256;
132 ireg.edx.w[0] = 0;
134 __intcall(0x10, &ireg, &oreg);
136 ireg.ebx.b[0] = 0;
137 ireg.eax.w[0] = 0x1103; /* Select page 0 */
138 __intcall(0x10, &ireg, NULL);
143 bios_adjust_screen();
147 * bios_adjust_screen: Set the internal variables associated with the screen size.
148 * This is a subroutine in case we're loading a custom font.
150 void bios_adjust_screen(void)
152 com32sys_t ireg, oreg;
153 volatile uint8_t *vidrows = (volatile uint8_t *)BIOS_vidrows;
154 uint8_t rows, cols;
156 rows = *vidrows;
157 if (!rows) {
159 * No vidrows in BIOS, assume 25.
160 * (Remember: vidrows == rows-1)
162 rows = 24;
165 VidRows = rows;
167 ireg.eax.b[1] = 0x0f; /* Read video state */
168 __intcall(0x10, &ireg, &oreg);
169 cols = oreg.eax.b[1];
171 VidCols = --cols; /* Store count-1 (same as rows) */
174 void adjust_screen(void)
176 if (firmware->adjust_screen)
177 firmware->adjust_screen();
180 void pm_adjust_screen(com32sys_t *regs __unused)
182 adjust_screen();
185 void pm_userfont(com32sys_t *regs)
187 regs->es = SEG(fontbuf);
188 regs->ebx.w[0] = OFFS(fontbuf);