• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <syslinux/video.h>
2 #include <com32.h>
3 #include <stdio.h>
4 #include <bios.h>
5 #include <graphics.h>
6 
7 static uint8_t TextAttribute;	/* Text attribute for message file */
8 extern uint8_t DisplayMask;	/* Display modes mask */
9 
10 /* Routine to interpret next print char */
11 static void (*NextCharJump)(uint8_t);
12 
13 void msg_initvars(void);
14 static void msg_setfg(uint8_t data);
15 static void msg_putchar(uint8_t ch);
16 
17 /*
18  *
19  * get_msg_file: Load a text file and write its contents to the screen,
20  *               interpreting color codes.
21  *
22  * Returns 0 on success, -1 on failure.
23  */
get_msg_file(char * filename)24 int get_msg_file(char *filename)
25 {
26 	FILE *f;
27 	char ch;
28 
29 	f = fopen(filename, "r");
30 	if (!f)
31 		return -1;
32 
33 	TextAttribute = 0x7;	/* Default grey on white */
34 	DisplayMask = 0x7;	/* Display text in all modes */
35 	msg_initvars();
36 
37 	/*
38 	 * Read the text file a byte at a time and interpret that
39 	 * byte.
40 	 */
41 	while ((ch = getc(f)) != EOF) {
42 		/* DOS EOF? */
43 		if (ch == 0x1A)
44 			break;
45 
46 		NextCharJump(ch);	/* Do what shall be done */
47 	}
48 
49 	DisplayMask = 0x07;
50 
51 	fclose(f);
52 	return 0;
53 }
54 
display_mask_vga(void)55 static inline int display_mask_vga(void)
56 {
57 	uint8_t mask = UsingVGA & 0x1;
58 	return (DisplayMask & ++mask);
59 }
60 
msg_setbg(uint8_t data)61 static void msg_setbg(uint8_t data)
62 {
63 	if (unhexchar(&data) == 0) {
64 		data <<= 4;
65 		if (display_mask_vga())
66 			TextAttribute = data;
67 
68 		NextCharJump = msg_setfg;
69 	} else {
70 		TextAttribute = 0x7;	/* Default attribute */
71 		NextCharJump = msg_putchar;
72 	}
73 }
74 
msg_setfg(uint8_t data)75 static void msg_setfg(uint8_t data)
76 {
77 	if (unhexchar(&data) == 0) {
78 		if (display_mask_vga()) {
79 			/* setbg set foreground to 0 */
80 			TextAttribute |= data;
81 		}
82 	} else
83 		TextAttribute = 0x7;	/* Default attribute */
84 
85 	NextCharJump = msg_putchar;
86 }
87 
msg_ctrl_o(void)88 static inline void msg_ctrl_o(void)
89 {
90 	NextCharJump = msg_setbg;
91 }
92 
93 /* Convert ANSI colors to PC display attributes */
94 static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
95 
set_fgbg(void)96 static void set_fgbg(void)
97 {
98 	uint8_t bg, fg;
99 
100 	fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
101 	bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
102 
103 	printf("\033[");
104 	if (TextAttribute & 0x8)
105 		printf("1;"); /* Foreground bright */
106 
107 	printf("3%dm\033[", fg);
108 
109 	if (TextAttribute & 0x80)
110 		printf("5;"); /* Foreground blink */
111 
112 	printf("4%dm", bg);
113 }
114 
msg_formfeed(void)115 static void msg_formfeed(void)
116 {
117 	set_fgbg();
118 	printf("\033[2J\033[H\033[0m");
119 }
120 
msg_novga(void)121 static void msg_novga(void)
122 {
123 	syslinux_force_text_mode();
124 	msg_initvars();
125 }
126 
msg_viewimage(void)127 static void msg_viewimage(void)
128 {
129 	FILE *f;
130 
131 	*VGAFilePtr = '\0';	/* Zero-terminate filename */
132 
133 	mangle_name(VGAFileMBuf, VGAFileBuf);
134 	f = fopen(VGAFileMBuf, "r");
135 	if (!f) {
136 		/* Not there */
137 		NextCharJump = msg_putchar;
138 		return;
139 	}
140 
141 	vgadisplayfile(f);
142 	fclose(f);
143 	msg_initvars();
144 }
145 
146 /*
147  * Getting VGA filename
148  */
msg_filename(uint8_t data)149 static void msg_filename(uint8_t data)
150 {
151 	/* <LF> = end of filename */
152 	if (data == 0x0A) {
153 		msg_viewimage();
154 		return;
155 	}
156 
157 	/* Ignore space/control char */
158 	if (data > ' ') {
159 		if ((char *)VGAFilePtr < (VGAFileBuf + sizeof(VGAFileBuf)))
160 			*VGAFilePtr++ = data;
161 	}
162 }
163 
msg_vga(void)164 static void msg_vga(void)
165 {
166 	NextCharJump = msg_filename;
167 	VGAFilePtr = (uint16_t *)VGAFileBuf;
168 }
169 
msg_normal(uint8_t data)170 static void msg_normal(uint8_t data)
171 {
172 	/* 0x1 = text mode, 0x2 = graphics mode */
173 	if (!display_mask_vga() || !(DisplayCon & 0x01)) {
174 		/* Write to serial port */
175 		if (DisplayMask & 0x4)
176 			write_serial(data);
177 
178 		return;		/* Not screen */
179 	}
180 
181 	set_fgbg();
182 	printf("%c\033[0m", data);
183 }
184 
msg_modectl(uint8_t data)185 static void msg_modectl(uint8_t data)
186 {
187 	data &= 0x07;
188 	DisplayMask = data;
189 	NextCharJump = msg_putchar;
190 }
191 
msg_putchar(uint8_t ch)192 static void msg_putchar(uint8_t ch)
193 {
194 	/* 10h to 17h are mode controls */
195 	if (ch >= 0x10 && ch < 0x18) {
196 		msg_modectl(ch);
197 		return;
198 	}
199 
200 	switch (ch) {
201 	case 0x0F:		/* ^O = color code follows */
202 		msg_ctrl_o();
203 		break;
204 	case 0x0D:		/* Ignore <CR> */
205 		break;
206 	case 0x0C:		/* <FF> = clear screen */
207 		msg_formfeed();
208 		break;
209 	case 0x19:		/* <EM> = return to text mode */
210 		msg_novga();
211 		break;
212 	case 0x18:		/* <CAN> = VGA filename follows */
213 		msg_vga();
214 		break;
215 	default:
216 		msg_normal(ch);
217 		break;
218 	}
219 }
220 
221 /*
222  * Subroutine to initialize variables, also needed after loading
223  * graphics file.
224  */
msg_initvars(void)225 void msg_initvars(void)
226 {
227 	/* Initialize state machine */
228 	NextCharJump = msg_putchar;
229 }
230