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