-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprint.c
More file actions
159 lines (130 loc) · 3.59 KB
/
print.c
File metadata and controls
159 lines (130 loc) · 3.59 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "print.h"
#include "io.h"
#include "pci21.h"
#define VGA_WIDTH 80
#define VGA_HEIGHT 25
#define VGA_COLOR_MEM 0xB8000
#define VGA_LIGHT_GRAY 0x07
#define CRTC_ADDRESS 0x3d4
#define CRTC_DATA 0x3d5
#define CRTC_CURS_LOC_HI 0xe
#define CRTC_CURS_LOC_LO 0xf
static uint8_t curs_row = 0;
static uint8_t curs_col = 0;
static char itoa_fixed[64];
static void move_vga_cursor(uint8_t column, uint8_t row) {
uint16_t pos = (uint16_t)(row * VGA_WIDTH + column);
outb(CRTC_ADDRESS, CRTC_CURS_LOC_LO);
outb(CRTC_DATA, (uint8_t)(pos & 0xFF));
outb(CRTC_ADDRESS, CRTC_CURS_LOC_HI);
outb(CRTC_DATA, (uint8_t)((pos >> 8) & 0xFF));
}
static void get_vga_cursor(uint8_t *column, uint8_t *row) {
uint16_t pos = 0;
outb(CRTC_ADDRESS, CRTC_CURS_LOC_LO);
pos |= inb(CRTC_DATA);
outb(CRTC_ADDRESS, CRTC_CURS_LOC_HI);
pos |= ((uint16_t)inb(CRTC_DATA)) << 8;
*row = (uint8_t)(pos / VGA_WIDTH);
*column = (uint8_t)(pos % VGA_WIDTH);
}
static void screen_scroll(void) {
volatile char *video_dst = (volatile char *)VGA_COLOR_MEM;
volatile char *video_src = video_dst + VGA_WIDTH * 2;
volatile char *video_end =
(volatile char *)VGA_COLOR_MEM + VGA_WIDTH * 2 * VGA_HEIGHT * 2;
while (video_src < video_end)
*video_dst++ = *video_src++;
for (uint8_t i = 0; i < VGA_WIDTH; i++) {
*video_dst++ = ' ';
*video_dst++ = VGA_LIGHT_GRAY;
}
}
static void advance_cursor_newline(void) {
if (curs_row + 1 == VGA_HEIGHT)
screen_scroll();
else
curs_row += 1;
curs_col = 0;
}
static void advance_cursor(void) {
if (curs_col + 1 == VGA_WIDTH)
advance_cursor_newline();
else
curs_col += 1;
}
void print_string(const char *string) {
while (*string != 0) {
volatile char *video = (volatile char *)VGA_COLOR_MEM
+ curs_row * VGA_WIDTH * 2 + curs_col * 2;
if (*string == '\n') {
advance_cursor_newline();
string++;
continue;
}
*video++ = *string++;
*video++ = VGA_LIGHT_GRAY;
advance_cursor();
}
move_vga_cursor(curs_col, curs_row);
}
void print_pci_dev(const struct pci_dev *pci_dev) {
char buf[8];
print_string(itoa(pci_dev->bus, buf, 10));
print_string(":");
print_string(itoa(pci_dev->device, buf, 10));
print_string(".");
print_string(itoa(pci_dev->func, buf, 10));
print_string(" ");
print_string(itoa(pci_dev->header.vendor_id, buf, 16));
print_string(":");
print_string(itoa(pci_dev->header.device_id, buf, 16));
print_string(" rev ");
print_string(itoa(pci_dev->header.rev_id, buf, 16));
print_string(" [");
print_string(itoa(pci_dev->header.class_code, buf, 16));
print_string(":");
print_string(itoa(pci_dev->header.subclass, buf, 16));
print_string("]");
print_string(" if ");
print_string(itoa(pci_dev->header.prog_if, buf, 16));
}
void init_output(void) {
get_vga_cursor(&curs_col, &curs_row);
print_string("\n");
}
// itoa OSDev Wiki implementation
char *itoa(int value, char *str, int base) {
char *rc;
char *ptr;
char *low;
if (base < 2 || base > 36) {
*str = '\0';
return str;
}
rc = ptr = str;
// Set '-' for negative decimals.
if (value < 0 && base == 10) {
*ptr++ = '-';
}
// Remember where the numbers start.
low = ptr;
// The actual conversion.
do {
// Modulo is negative for negative value. This trick makes abs()
// unnecessary.
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnop"
"qrstuvwxyz"[35 + value % base];
value /= base;
} while (value);
// Terminating the string.
*ptr-- = '\0';
// Invert the numbers.
while (low < ptr) {
char tmp = *low;
*low++ = *ptr;
*ptr-- = tmp;
}
return rc;
}
char *itoa_once(int value, int base) { return itoa(value, itoa_fixed, base); }