Home | History | Annotate | Download | only in core
      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