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
|
#include "colours.h"
#define COLS (80 * 2) // 2 bytes per char
#define ROWS 25
#define FRAME_SIZE (ROWS * COLS)
char *video_ram = (char *) 0xB8000;
int cursor_pos = 0;
int char_attribute_byte = 0x0F;
extern void write_port(unsigned short port, unsigned char data);
extern char read_port(unsigned short port);
void scrn_enable_cursor(unsigned char start_line, unsigned char end_line)
{
write_port(0x3D4, 0x0A);
write_port(0x3D5, (read_port(0x3D5) & 0xC0) | start_line);
write_port(0x3D4, 0x0B);
write_port(0x3D5, (read_port(0x3D5) & 0xE0) | end_line);
}
void scrn_update_csr()
{
unsigned short csr = cursor_pos/2;
write_port(0x3D4, 14);
write_port(0x3D5, csr >> 8);
write_port(0x3D4, 15);
write_port(0x3D5, csr);
}
void scrn_clear()
{
for (int i = 0; i < FRAME_SIZE; i = i + 2)
{
video_ram[i] = 0;
video_ram[i + 1] = char_attribute_byte;
};
cursor_pos = 0;
}
void scrn_set_text_colour(int foreground, int background)
{
char_attribute_byte = (background << 4) | foreground;
}
int scrn_get_char_attr_byte() {
return char_attribute_byte;
}
void scrn_set_char_attr_byte(int byte) {
char_attribute_byte = byte;
}
void scrn_putchar(unsigned char c)
{
video_ram[cursor_pos++] = c;
video_ram[cursor_pos++] = char_attribute_byte;
scrn_update_csr();
}
// TODO - jump cursor to prev non 0 text char rather than reversing through whole array
void scrn_backspace()
{
if (cursor_pos != 0)
{
video_ram[--cursor_pos] = char_attribute_byte;
video_ram[--cursor_pos] = 0;
scrn_update_csr();
}
}
void scrn_newline()
{
int current_line = cursor_pos / COLS;
cursor_pos = (current_line + 1) * COLS;
scrn_update_csr();
}
void scrn_print(char *msg)
{
int j = 0;
while (msg[j] != '\0')
{
video_ram[cursor_pos++] = msg[j];
video_ram[cursor_pos++] = char_attribute_byte;
++j;
}
scrn_update_csr();
}
void scrn_println(char *msg)
{
scrn_print(msg);
scrn_newline();
}
void scrn_set_cursor_pos(unsigned int row, unsigned int col)
{
cursor_pos = (row * COLS) + (col * 2);
scrn_update_csr();
}
int scrn_get_cursor_row()
{
// 0 index
return cursor_pos / COLS;
}
int scrn_get_cursor_col()
{
return (cursor_pos % COLS)/2;
}
|