fs.h: A slighly more useful default PATH
[syslinux.git] / core / font.c
blob1fcbbe83f51b2428cee3be1bede01a1474e1f3ba
1 /*
2 * -----------------------------------------------------------------------
4 * Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
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 * -----------------------------------------------------------------------
15 * font.c
17 * VGA font handling code
21 #include <sys/io.h>
22 #include <stdio.h>
23 #include <fs.h>
24 #include "bios.h"
25 #include "core.h"
27 char fontbuf[8192];
28 char serial[serial_buf_size];
30 extern uint16_t VGAFontSize;
31 extern uint8_t UserFont;
33 uint16_t GXPixCols = 1; /* Graphics mode pixel columns */
34 uint16_t GXPixRows = 1; /* Graphics mode pixel rows */
37 * loadfont: Load a .psf font file and install it onto the VGA console
38 * (if we're not on a VGA screen then ignore.)
40 * The .psf font file must alredy be open and getc_file must be set.
42 void loadfont(char *filename)
44 uint16_t height, magic;
45 uint32_t *di, *si;
46 FILE *f;
47 char *p;
48 int i;
50 f = fopen(filename, "r");
51 if (!f)
52 return;
54 p = trackbuf;
55 /* Read header */
56 for (i = 0; i < 4; i++) {
57 char ch = getc(f);
58 if (ch == EOF)
59 return;
60 *p++ = ch;
63 /* Magic number */
64 magic = *(uint16_t *)trackbuf;
65 if (magic != 0x0436)
66 return;
68 /* File mode: font modes 0-5 supported */
69 if (*(trackbuf) > 5)
70 return;
72 height = *(trackbuf + 3); /* Height of font */
74 /* VGA minimum/maximum */
75 if (height < 2 || height > 32)
76 return;
78 /* Load the actual font. Bytes = font height * 256 */
79 p = trackbuf;
80 for (i = 0; i < (height << 8); i++) {
81 char ch = getc(f);
83 if (ch == EOF)
84 return;
85 *p++ = ch;
88 /* Copy to font buffer */
89 VGAFontSize = height;
90 di = (uint32_t *)fontbuf;
91 si = (uint32_t *)trackbuf;
92 for (i = 0; i < (height << 6); i++)
93 *di++ = *si++;
95 UserFont = 1; /* Set font flag */
96 use_font();
100 * use_font:
101 * This routine activates whatever font happens to be in the
102 * vgafontbuf, and updates the adjust_screen data.
103 * Must be called with CS = DS
105 void use_font(void)
107 com32sys_t ireg, oreg;
108 uint8_t bytes = VGAFontSize;
111 /* Nonstandard mode? */
112 if (UsingVGA & ~0x3)
113 vgaclearmode();
115 memset(&ireg, 0, sizeof(ireg));
117 ireg.es = SEG(fontbuf);
118 ireg.ebp.w[0] = OFFS(fontbuf); /* ES:BP -> font */
120 /* Are we using a user-specified font? */
121 if (UserFont & 0x1) {
122 /* Are we in graphics mode? */
123 if (UsingVGA & 0x1) {
124 uint8_t rows;
126 rows = GXPixRows / bytes;
127 VidRows = rows - 1;
129 /* Set user character table */
130 ireg.eax.w[0] = 0x1121;
131 ireg.ebx.b[0] = 0;
132 ireg.ecx.b[0] = bytes; /* bytes/character */
133 ireg.edx.b[0] = rows;
135 __intcall(0x10, &ireg, &oreg);
137 /* 8 pixels/character */
138 VidCols = ((GXPixCols >> 3) - 1);
140 /* No need to call adjust_screen */
141 return;
142 } else {
143 ireg.eax.w[0] = 0x1110; /* Load into VGA RAM */
144 ireg.ebx.b[0] = 0;
145 ireg.ebx.b[1] = bytes; /* bytes/character */
146 ireg.ecx.w[0] = 256;
147 ireg.edx.w[0] = 0;
149 __intcall(0x10, &ireg, &oreg);
151 ireg.ebx.b[0] = 0;
152 ireg.eax.w[0] = 0x1103; /* Select page 0 */
153 __intcall(0x10, &ireg, NULL);
157 adjust_screen();
161 * adjust_screen: Set the internal variables associated with the screen size.
162 * This is a subroutine in case we're loading a custom font.
164 void adjust_screen(void)
166 com32sys_t ireg, oreg;
167 volatile uint8_t *vidrows = (volatile uint8_t *)BIOS_vidrows;
168 uint8_t rows, cols;
170 rows = *vidrows;
171 if (!rows) {
173 * No vidrows in BIOS, assume 25.
174 * (Remember: vidrows == rows-1)
176 rows = 24;
179 VidRows = rows;
181 ireg.eax.b[1] = 0x0f; /* Read video state */
182 __intcall(0x10, &ireg, &oreg);
183 cols = oreg.eax.b[1];
185 VidCols = --cols; /* Store count-1 (same as rows) */
188 void pm_adjust_screen(com32sys_t *regs __unused)
190 adjust_screen();
193 void pm_userfont(com32sys_t *regs)
195 regs->es = SEG(fontbuf);
196 regs->ebx.w[0] = OFFS(fontbuf);