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 */ 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 55 static inline int display_mask_vga(void) 56 { 57 uint8_t mask = UsingVGA & 0x1; 58 return (DisplayMask & ++mask); 59 } 60 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 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 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 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 115 static void msg_formfeed(void) 116 { 117 set_fgbg(); 118 printf("\033[2J\033[H\033[0m"); 119 } 120 121 static void msg_novga(void) 122 { 123 syslinux_force_text_mode(); 124 msg_initvars(); 125 } 126 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 */ 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 164 static void msg_vga(void) 165 { 166 NextCharJump = msg_filename; 167 VGAFilePtr = (uint16_t *)VGAFileBuf; 168 } 169 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 185 static void msg_modectl(uint8_t data) 186 { 187 data &= 0x07; 188 DisplayMask = data; 189 NextCharJump = msg_putchar; 190 } 191 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 */ 225 void msg_initvars(void) 226 { 227 /* Initialize state machine */ 228 NextCharJump = msg_putchar; 229 } 230