com32/chain: remove unused ebr_start
[syslinux/sherbszt.git] / core / font.c
blob853308080ad31f661e5ec8936f2ac5e3f2be786a
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>
25 #include "bios.h"
26 #include "graphics.h"
27 #include "core.h"
29 __export uint8_t UserFont = 0; /* Using a user-specified font */
31 __export __lowmem char fontbuf[8192];
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 __export void loadfont(const char *filename)
42 struct psfheader {
43 uint16_t magic;
44 uint8_t mode;
45 uint8_t height;
46 } hdr;
47 FILE *f;
48 char *p;
49 int i;
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);
74 p = fontbuf;
75 for (i = 0; i < 256; i++) {
76 if (_fread(p, hdr.height, f) != hdr.height)
77 goto fail;
78 p += 32;
81 /* Loaded OK */
82 VGAFontSize = hdr.height;
83 UserFont = 1; /* Set font flag */
84 use_font();
86 fail:
87 fclose(f);
91 * use_font:
92 * This routine activates whatever font happens to be in the
93 * vgafontbuf, and updates the adjust_screen data.
94 * Must be called with CS = DS
96 void use_font(void)
98 com32sys_t ireg, oreg;
99 uint8_t bytes = VGAFontSize;
101 /* Nonstandard mode? */
102 if (UsingVGA & ~0x3)
103 syslinux_force_text_mode();
105 memset(&ireg, 0, sizeof(ireg));
107 ireg.es = SEG(fontbuf);
108 ireg.ebp.w[0] = OFFS(fontbuf); /* ES:BP -> font */
110 /* Are we using a user-specified font? */
111 if (UserFont & 0x1) {
112 /* Are we in graphics mode? */
113 if (UsingVGA & 0x1) {
114 uint8_t rows;
116 rows = GXPixRows / bytes;
117 VidRows = rows - 1;
119 /* Set user character table */
120 ireg.eax.w[0] = 0x1121;
121 ireg.ebx.b[0] = 0;
122 ireg.ecx.b[0] = bytes; /* bytes/character */
123 ireg.edx.b[0] = rows;
125 __intcall(0x10, &ireg, &oreg);
127 /* 8 pixels/character */
128 VidCols = ((GXPixCols >> 3) - 1);
130 /* No need to call adjust_screen */
131 return;
132 } else {
133 ireg.eax.w[0] = 0x1110; /* Load into VGA RAM */
134 ireg.ebx.b[0] = 0;
135 ireg.ebx.b[1] = bytes; /* bytes/character */
136 ireg.ecx.w[0] = 256;
137 ireg.edx.w[0] = 0;
139 __intcall(0x10, &ireg, &oreg);
141 ireg.ebx.b[0] = 0;
142 ireg.eax.w[0] = 0x1103; /* Select page 0 */
143 __intcall(0x10, &ireg, NULL);
147 adjust_screen();
151 * adjust_screen: Set the internal variables associated with the screen size.
152 * This is a subroutine in case we're loading a custom font.
154 void adjust_screen(void)
156 com32sys_t ireg, oreg;
157 volatile uint8_t *vidrows = (volatile uint8_t *)BIOS_vidrows;
158 uint8_t rows, cols;
160 rows = *vidrows;
161 if (!rows) {
163 * No vidrows in BIOS, assume 25.
164 * (Remember: vidrows == rows-1)
166 rows = 24;
169 VidRows = rows;
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 pm_adjust_screen(com32sys_t *regs __unused)
180 adjust_screen();
183 void pm_userfont(com32sys_t *regs)
185 regs->es = SEG(fontbuf);
186 regs->ebx.w[0] = OFFS(fontbuf);