Merging upstream version 5.01+dfsg.
[syslinux-debian/hramrach.git] / com32 / elflink / ldlinux / msg.c
blob9ded33ef6028f25935082cfa349edb20c0c26031
1 #include <com32.h>
2 #include <stdio.h>
3 #include <bios.h>
4 #include <graphics.h>
6 static uint8_t TextAttribute; /* Text attribute for message file */
7 extern uint8_t DisplayMask; /* Display modes mask */
9 /* Routine to interpret next print char */
10 static void (*NextCharJump)(uint8_t);
12 void msg_initvars(void);
13 static void msg_setfg(uint8_t data);
14 static void msg_putchar(uint8_t ch);
18 * get_msg_file: Load a text file and write its contents to the screen,
19 * interpreting color codes.
21 * Returns 0 on success, -1 on failure.
23 int get_msg_file(char *filename)
25 FILE *f;
26 char ch;
28 f = fopen(filename, "r");
29 if (!f)
30 return -1;
32 TextAttribute = 0x7; /* Default grey on white */
33 DisplayMask = 0x7; /* Display text in all modes */
34 msg_initvars();
37 * Read the text file a byte at a time and interpret that
38 * byte.
40 while ((ch = getc(f)) != EOF) {
41 /* DOS EOF? */
42 if (ch == 0x1A)
43 break;
45 NextCharJump(ch); /* Do what shall be done */
48 DisplayMask = 0x07;
50 fclose(f);
51 return 0;
54 static inline int display_mask_vga(void)
56 uint8_t mask = UsingVGA & 0x1;
57 return (DisplayMask & ++mask);
60 static void msg_setbg(uint8_t data)
62 if (unhexchar(&data) == 0) {
63 data <<= 4;
64 if (display_mask_vga())
65 TextAttribute = data;
67 NextCharJump = msg_setfg;
68 } else {
69 TextAttribute = 0x7; /* Default attribute */
70 NextCharJump = msg_putchar;
74 static void msg_setfg(uint8_t data)
76 if (unhexchar(&data) == 0) {
77 if (display_mask_vga()) {
78 /* setbg set foreground to 0 */
79 TextAttribute |= data;
81 } else
82 TextAttribute = 0x7; /* Default attribute */
84 NextCharJump = msg_putchar;
87 static inline void msg_ctrl_o(void)
89 NextCharJump = msg_setbg;
92 /* Convert ANSI colors to PC display attributes */
93 static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
95 static void set_fgbg(void)
97 uint8_t bg, fg;
99 fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
100 bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
102 printf("\033[");
103 if (TextAttribute & 0x8)
104 printf("1;"); /* Foreground bright */
106 printf("3%dm\033[", fg);
108 if (TextAttribute & 0x80)
109 printf("5;"); /* Foreground blink */
111 printf("4%dm", bg);
114 static void msg_formfeed(void)
116 set_fgbg();
117 printf("\033[2J\033[H\033[0m");
120 static void msg_novga(void)
122 syslinux_force_text_mode();
123 msg_initvars();
126 static void msg_viewimage(void)
128 FILE *f;
130 *VGAFilePtr = '\0'; /* Zero-terminate filename */
132 mangle_name(VGAFileMBuf, VGAFileBuf);
133 f = fopen(VGAFileMBuf, "r");
134 if (!f) {
135 /* Not there */
136 NextCharJump = msg_putchar;
137 return;
140 vgadisplayfile(f);
141 fclose(f);
142 msg_initvars();
146 * Getting VGA filename
148 static void msg_filename(uint8_t data)
150 /* <LF> = end of filename */
151 if (data == 0x0A) {
152 msg_viewimage();
153 return;
156 /* Ignore space/control char */
157 if (data > ' ') {
158 if ((char *)VGAFilePtr < (VGAFileBuf + sizeof(VGAFileBuf)))
159 *VGAFilePtr++ = data;
163 static void msg_vga(void)
165 NextCharJump = msg_filename;
166 VGAFilePtr = (uint16_t *)VGAFileBuf;
169 static void msg_normal(uint8_t data)
171 /* 0x1 = text mode, 0x2 = graphics mode */
172 if (!display_mask_vga() || !(DisplayCon & 0x01)) {
173 /* Write to serial port */
174 if (DisplayMask & 0x4)
175 write_serial(data);
177 return; /* Not screen */
180 set_fgbg();
181 printf("%c\033[0m", data);
184 static void msg_modectl(uint8_t data)
186 data &= 0x07;
187 DisplayMask = data;
188 NextCharJump = msg_putchar;
191 static void msg_putchar(uint8_t ch)
193 /* 10h to 17h are mode controls */
194 if (ch >= 0x10 && ch < 0x18) {
195 msg_modectl(ch);
196 return;
199 switch (ch) {
200 case 0x0F: /* ^O = color code follows */
201 msg_ctrl_o();
202 break;
203 case 0x0D: /* Ignore <CR> */
204 break;
205 case 0x0C: /* <FF> = clear screen */
206 msg_formfeed();
207 break;
208 case 0x19: /* <EM> = return to text mode */
209 msg_novga();
210 break;
211 case 0x18: /* <CAN> = VGA filename follows */
212 msg_vga();
213 break;
214 default:
215 msg_normal(ch);
216 break;
221 * Subroutine to initialize variables, also needed after loading
222 * graphics file.
224 void msg_initvars(void)
226 /* Initialize state machine */
227 NextCharJump = msg_putchar;