• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
writechr(char data)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 
pm_writechr(com32sys_t * regs)92 void pm_writechr(com32sys_t *regs)
93 {
94 	writechr(regs->eax.b[0]);
95 }
96