aboutsummaryrefslogtreecommitdiff
path: root/kernel/gpu/text_mode/display.c
blob: 3758c7160176abded7a8e9898c17a414e5b8f78c (plain)
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;
}