-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscreen.c
135 lines (118 loc) · 3.36 KB
/
screen.c
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
/* screen.c - Screen I/O functions
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-
* ShareAlike 3.0 Unported License. To view a copy of this license, visit
* http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to:
* Creative Commons
* 444 Castro Street, Suite 900
* Mountain View, California, 94041, USA.
*
* Author(s): Drew Cross <drew@ddcross.com>
*/
#include "screen.h"
// VGA framebuffer starts at 0xB8000;
u16int *video_memory = (u16int *)0xB8000;
//Stores cursor position
u8int cursor_x = 0;
u8int cursor_y = 0;
static void scroll()
{
// Get a space character with the default color atributes.
u8int attributeByte = (0 << 4) | (15 & 0x0F); //(Black) | (White)
u16int blank = 0x20 | (attributeByte << 8); // Space |
// Row 25 is the end, this means we need to scroll up
if(cursor_y >= 25)
{
// Move the current text chunk tha tmakes up the screen
// back in the buffer by a line
int i;
for (i = 0*80; i < 24*80; i++)
{
video_memory[i] = video_memory[i+80];
}
for(i = 24*80; i < 25*80; i++)
{
video_memory[i] = blank;
}
// The cursor should now be on the last line.
cursor_y = 24;
}
}
static void move_cursor()
{
//Screen is 80x25 -
u16int cursorLocation = cursor_y * 80 + cursor_x;
outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte.
outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte.
outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte.
outb(0x3D5, cursorLocation); // Send the low cursor byte.
}
void screen_clear()
{
// Set attrByte
u8int attributeByte = (0 << 4) | (15 & 0x0F);
u16int blank = 0x20 | (attributeByte << 8);
int i;
for(i =0; i < 80*25; i++)
{
video_memory[i] = blank;
}
// Move hardware cursor to beginning
cursor_x = 0;
cursor_y = 0;
move_cursor();
}
void screen_put(char c)
{
u8int backColor = 0; //Black
u8int foreColor = 15; //White
//The lower of this is the foreground and the upper nyble is the background
u8int attributeByte = (backColor << 4) | (foreColor & 0x0f); // This is the byte we send to the VGA board
u16int attribute = attributeByte << 8;
u16int *location;
// Backspace handling
if(c == 0x08 && cursor_x) {
cursor_x --;
}
// Tab handling
else if(c == 0x09)
{
cursor_x = (cursor_x+8) & ~(8-1);
}
// Carriage return handling
else if (c == '\r')
{
cursor_x = 0;
}
// Newline handling
else if(c == '\n')
{
cursor_x = 0;
cursor_y++;
}
// Other characters => output
else if(c >= ' ')//TODO: Do i need a <= 'Z'
{
location = video_memory + (cursor_y*80 + cursor_x);
*location = c | attribute;// Attribute was shifted left 8 bits, so we're setting the characeter 'c' to attribute
cursor_x++; // and we're setting that to location
}
// Check end of the screen
if(cursor_x >= 80)
{
cursor_x = 0;
cursor_y++;
}
// Scroll if necessary
scroll();
// Move hardware cursor
move_cursor();
}
void screen_write(char * c)
{
int i = 0;
while(c[i])
{
screen_put(c[i++]);
}
}