1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#include "print.h"
#define FOREGROUND 0x0
#define BACKGROUND 0xF
TextOutput createOutput(const int max_row, const int max_column, uint16_t* vid_mem) {
// Create a new TextOutput interface
TextOutput output;
output.max_row = max_row;
output.max_column = max_column;
output.vid_mem = vid_mem;
output.terminal_row = 0;
output.terminal_column = 0;
return output;
}
void scrollText(TextOutput* textOutput) {
// Move each character up one row
for (int y = 0; y < textOutput->max_row; y++) {
for (int x = 0; x < textOutput->max_column; x++) {
*(textOutput->vid_mem + textOutput->max_column*y + x) =
*(textOutput->vid_mem + textOutput->max_column*(y+1) + x);
}
}
textOutput->terminal_row--;
}
void putChar(uint8_t character, uint8_t background, uint8_t foreground,
TextOutput* textOutput) {
foreground = foreground & 0xF; background = background & 0xF;
// Handle putting a character to the screen
if (textOutput->terminal_row == textOutput->max_row) {
scrollText(textOutput);
}
if (character == '\r') {
// Delete the character before this \r
if (textOutput->terminal_column == 0) {
textOutput->terminal_row--;
textOutput->terminal_column = 80;
}
textOutput->terminal_column--;
*(textOutput->vid_mem + textOutput->terminal_row*textOutput->max_column
+ textOutput->terminal_column) = background << 12;
return;
}
else if (character == '\n' || textOutput->terminal_column == textOutput->max_column) {
// Make a new line
for (int i = textOutput->terminal_column; i < textOutput->max_column; i++) {
*(textOutput->vid_mem + textOutput->terminal_row*textOutput->max_column
+ textOutput->terminal_column) = background << 12;
textOutput->terminal_column++;
}
textOutput->terminal_row++;
textOutput->terminal_column = 0;
}
if (character != '\n' && character != '\r') {
// Write character to video memory
uint16_t entry = (background << 12) | (foreground << 8) | character;
*(textOutput->vid_mem + textOutput->terminal_row*textOutput->max_column
+ textOutput->terminal_column) = entry;
textOutput->terminal_column++;
}
}
void print(char* string, uint8_t background, uint8_t foreground, TextOutput* textOutput) {
// Print a string
while (*string) {
putChar(*string, background, foreground, textOutput);
string++;
}
}
void PrintWithScreenFill(char* string, TextOutput* output_stream) {
// Print a string and fill the screen
print(string, BACKGROUND, FOREGROUND, output_stream);
int row = output_stream->terminal_row;
while (output_stream->terminal_row < output_stream->max_row) {
putChar('\n', BACKGROUND, FOREGROUND, output_stream);
}
output_stream->terminal_row = row;
}
inline void swap(char *x, char *y) {
char t = *x; *x = *y; *y = t;
}
int abs(int value) {
return (value < 0 ? -value : value);
}
// function to reverse buffer[i..j]
char* reverse(char *buffer, int i, int j)
{
while (i < j)
swap(&buffer[i++], &buffer[j--]);
return buffer;
}
// Iterative function to implement itoa() function in C
char* itoa(int value, char* buffer, int base)
{
if (base < 2 || base > 32)
return buffer;
int n = abs(value);
int i = 0;
while (n)
{
int r = n % base;
if (r >= 10)
buffer[i++] = 65 + (r - 10);
else
buffer[i++] = 48 + r;
n = n / base;
}
if (i == 0)
buffer[i++] = '0';
if (value < 0 && base == 10)
buffer[i++] = '-';
buffer[i] = '\0';
return reverse(buffer, 0, i - 1);
}
int haveFilledScreen = 0;
void printToMonitor(char* string) {
if (!haveFilledScreen) {
monitor = createOutput(25, 80, (uint16_t*)(0xB8000));
PrintWithScreenFill(string, &monitor);
haveFilledScreen = 1;
}
else
print(string, BACKGROUND, FOREGROUND, &monitor);
}
void printIntToMonitor(int num, int base) {
char* buffer;
printToMonitor(itoa(num, buffer, base));
}
|