1 /* 2 * writechr: Write a single character in AL to the console without 3 * mangling any registers. This does raw console writes, 4 * since some PXE BIOSes seem to interfere regular console I/O. 5 */ 6 #include <sys/io.h> 7 #include <fs.h> 8 #include <com32.h> 9 10 #include "bios.h" 11 #include "graphics.h" 12 #include <syslinux/video.h> 13 14 __export void writechr(char data) 15 { 16 if (UsingVGA & 0x08) 17 syslinux_force_text_mode(); 18 19 write_serial(data); /* write to serial port if needed */ 20 21 /* Write to screen? */ 22 if (DisplayCon & 0x01) { 23 com32sys_t ireg, oreg; 24 bool curxyok = false; 25 uint16_t dx; 26 27 memset(&ireg, 0, sizeof ireg); 28 ireg.ebx.b[1] = *(uint8_t *)BIOS_page; 29 ireg.eax.b[1] = 0x03; /* Read cursor position */ 30 __intcall(0x10, &ireg, &oreg); 31 ireg.edx.l = oreg.edx.l; 32 33 switch (data) { 34 case 8: 35 if (ireg.edx.b[0]--) { 36 curxyok = true; 37 break; 38 } 39 40 ireg.edx.b[0] = VidCols; 41 if (ireg.edx.b[1]--) { 42 curxyok = true; 43 break; 44 } 45 46 ireg.edx.b[1] = 0; 47 curxyok = true; 48 break; 49 case 13: 50 ireg.edx.b[0] = 0; 51 curxyok = true; 52 break; 53 case 10: 54 break; 55 default: 56 dx = ireg.edx.w[0]; 57 58 ireg.ebx.b[1] = *(uint8_t *)BIOS_page; 59 ireg.ebx.b[0] = 0x07; /* White on black */ 60 ireg.ecx.w[0] = 1; /* One only */ 61 ireg.eax.b[0] = data; 62 ireg.eax.b[1] = 0x09; /* Write char and attribute */ 63 __intcall(0x10, &ireg, NULL); 64 65 ireg.edx.w[0] = dx; 66 if (++ireg.edx.b[0] <= VidCols) 67 curxyok = true; 68 else 69 ireg.edx.b[0] = 0; 70 } 71 72 if (!curxyok && ++ireg.edx.b[1] > VidRows) { 73 /* Scroll */ 74 ireg.edx.b[1]--; 75 ireg.ebx.b[1] = *(uint8_t *)BIOS_page; 76 ireg.eax.b[1] = 0x02; 77 __intcall(0x10, &ireg, NULL); 78 79 ireg.eax.w[0] = 0x0601; /* Scroll up one line */ 80 ireg.ebx.b[1] = ScrollAttribute; 81 ireg.ecx.w[0] = 0; 82 ireg.edx.w[0] = ScreenSize; /* The whole screen */ 83 __intcall(0x10, &ireg, NULL); 84 } else { 85 ireg.ebx.b[1] = *(uint8_t *)BIOS_page; 86 ireg.eax.b[1] = 0x02; /* Set cursor position */ 87 __intcall(0x10, &ireg, NULL); 88 } 89 } 90 } 91 92 void pm_writechr(com32sys_t *regs) 93 { 94 writechr(regs->eax.b[0]); 95 } 96