The Pedigree Project 0.1
BootIO.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/core/BootIO.h"
22#include "pedigree/kernel/machine/Machine.h"
23#include "pedigree/kernel/machine/Serial.h"
24#include "pedigree/kernel/machine/Vga.h"
25#include "pedigree/kernel/processor/types.h"
26#include "pedigree/kernel/utilities/StaticString.h"
27
28BootIO::BootIO() NOTHROW : m_CursorX(0), m_CursorY(0) {}
29
31
33 Vga* pVga = Machine::instance().getVga(0);
34 if (pVga) {
35 pVga->setLargestTextMode();
36 uint16_t* pFramebuffer = *pVga;
37 if (pFramebuffer != 0)
38 for (size_t i = 0; i < pVga->getNumRows() * pVga->getNumCols(); i++)
39 pFramebuffer[i] = 0;
40 }
41
43 str += "BootIO is initialized!\n";
44 write(str, Black, Black);
45}
46
47template <class T>
48void BootIO::write(T& str, Colour foreColour, Colour backColour) {
49 for (size_t i = 0; i < str.length(); i++)
50 putCharVga(str[i], foreColour, backColour);
51 Vga* pVga = Machine::instance().getVga(0);
52 if (pVga)
53 pVga->flush();
54 if (Log::instance().echoToSerial()) {
55#if !SERIAL_IS_FILE
56 startColour(Machine::instance().getSerial(0), foreColour, backColour);
57#endif
58 for (size_t j = 0; j < str.length(); j++)
59 Machine::instance().getSerial(0)->write(str[j]);
60#if !SERIAL_IS_FILE
61 endColour(Machine::instance().getSerial(0));
62#endif
63 }
64}
65
66void BootIO::putCharVga(const char c, Colour foreColour, Colour backColour) {
67 Vga* pVga = Machine::instance().getVga(0);
68 if (pVga) {
69 uint16_t* pFramebuffer = *pVga;
70 if (pFramebuffer == 0)
71 return;
72 // Backspace?
73 if (c == 0x08) {
74 // Can we just move backwards? or do we have to go up?
75 if (m_CursorX)
76 m_CursorX--;
77 else {
78 m_CursorX = pVga->getNumCols() - 1;
79 if (m_CursorY > 0)
80 m_CursorY--;
81 }
82
83 // Erase the contents of the cell currently.
84 uint8_t attributeByte = (backColour << 4) | (foreColour & 0x0F);
85 pFramebuffer[m_CursorY * pVga->getNumCols() + m_CursorX] = ' ' | (attributeByte << 8);
86 }
87
88 // Tab?
89 else if (c == 0x09 && (((m_CursorX + 8) & ~(8 - 1)) < pVga->getNumCols()))
90 m_CursorX = (m_CursorX + 8) & ~(8 - 1);
91
92 // Carriage return?
93 else if (c == '\r')
94 m_CursorX = 0;
95
96 // Newline?
97 else if (c == '\n') {
98 m_CursorX = 0;
99 m_CursorY++;
100 }
101
102 // Normal character?
103 else if (c >= ' ') {
104 uint8_t attributeByte = (backColour << 4) | (foreColour & 0x0F);
105 pFramebuffer[m_CursorY * pVga->getNumCols() + m_CursorX] = c | (attributeByte << 8);
106
107 // Increment the cursor.
108 m_CursorX++;
109 }
110
111 // Do we need to wrap?
112 if (m_CursorX >= pVga->getNumCols()) {
113 m_CursorX = 0;
114 m_CursorY++;
115 }
116
117 // Get a space character with the default colour attributes.
118 uint8_t attributeByte = (Black << 4) | (White & 0x0F);
119 uint16_t blank = ' ' | (attributeByte << 8);
120 if (m_CursorY >= pVga->getNumRows()) {
121 for (size_t i = 0; i < (pVga->getNumRows() - 1) * pVga->getNumCols(); i++)
122 pFramebuffer[i] = pFramebuffer[i + pVga->getNumCols()];
123
124 for (size_t i = (pVga->getNumRows() - 1) * pVga->getNumCols();
125 i < (pVga->getNumRows()) * pVga->getNumCols(); i++)
126 pFramebuffer[i] = blank;
127
128 m_CursorY = pVga->getNumRows() - 1;
129 }
130 }
131}
132
133void BootIO::startColour(Serial* pSerial, Colour foreColour, Colour backColour) {
134 pSerial->write_str("\033[");
135 switch (foreColour) {
136 case Black:
137 pSerial->write_str("30");
138 break;
139 case Red:
140 pSerial->write_str("31");
141 break;
142 case Green:
143 pSerial->write_str("32");
144 break;
145 case Yellow:
146 pSerial->write_str("1;33");
147 break; // It's actually brown.
148 case Blue:
149 pSerial->write_str("34");
150 break;
151 case Magenta:
152 pSerial->write_str("35");
153 break;
154 case Cyan:
155 pSerial->write_str("36");
156 break;
157 case LightGrey:
158 pSerial->write_str("0;37");
159 break;
160 case DarkGrey:
161 pSerial->write_str("1;30");
162 break;
163 case LightRed:
164 pSerial->write_str("1;31");
165 break;
166 case LightGreen:
167 pSerial->write_str("1;32");
168 break;
169 case LightBlue:
170 pSerial->write_str("1;34");
171 break;
172 case LightMagenta:
173 pSerial->write_str("1;35");
174 break;
175 case LightCyan:
176 pSerial->write_str("1;36");
177 break;
178 case White:
179 pSerial->write_str("1;37");
180 break;
181 default:
182 pSerial->write('1');
183 }
184 pSerial->write_str(";");
185 switch (backColour) {
186 case Black:
187 pSerial->write_str("40");
188 break;
189 case Red:
190 pSerial->write_str("41");
191 break;
192 case Green:
193 pSerial->write_str("42");
194 break;
195 case DarkGrey:
196 pSerial->write_str("43");
197 break; // It's actually brown.
198 case Blue:
199 pSerial->write_str("44");
200 break;
201 case Magenta:
202 pSerial->write_str("45");
203 break;
204 case Cyan:
205 pSerial->write_str("46");
206 break;
207 case White:
208 pSerial->write_str("47");
209 break;
210 default:
211 pSerial->write('1');
212 }
213 pSerial->write('m');
214}
215
216void BootIO::endColour(Serial* pSerial) {}
217
218template EXPORTED_PUBLIC void BootIO::write<TinyStaticString>(TinyStaticString& str,
219 Colour foreColour, Colour backColour);
220template EXPORTED_PUBLIC void BootIO::write<NormalStaticString>(NormalStaticString& str,
221 Colour foreColour,
222 Colour backColour);
223template EXPORTED_PUBLIC void BootIO::write<LargeStaticString>(LargeStaticString& str,
224 Colour foreColour,
225 Colour backColour);
226template EXPORTED_PUBLIC void BootIO::write<HugeStaticString>(HugeStaticString& str,
227 Colour foreColour, Colour backColour);
EXPORTED_PUBLIC void write(T &str, Colour foreColour, Colour backColour)
~BootIO()
Definition BootIO.cc:30
void initialise()
Definition BootIO.cc:32
BootIO() NOTHROW
Definition BootIO.cc:28
size_t m_CursorX
Definition BootIO.h:84
static EXPORTED_PUBLIC Log & instance()
Definition Log.cc:117
virtual Vga * getVga(size_t n)=0
virtual bool setLargestTextMode()=0
virtual size_t getNumRows()=0
virtual size_t getNumCols()=0