/
screen.c
154 lines (133 loc) · 3.72 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "screen.h"
//FIXME: OK, atneztem, ertheto a kod...
char buffer[16]; // int -> string
unsigned short *textmemptr;
int attrib= 0x0F; //text color 15 - White
int csr_x=0,csr_y=0;
void scroll(void){
unsigned blank= 0x20 |(attrib << 8); //Space character, black background
if(csr_y>=25){
//after 25 lines we must scroll the screen
// memcpy(textmemptr,textmemptr+(csr_y-25+1)*80,(25-csr_y-25+1)*80*2);
memcpy(textmemptr,textmemptr+80,24*80*2);
memsetw(textmemptr+(25-(csr_y-25+1))*80,blank,80);
// csr_y=25-1;
csr_y=24;
};
};
void move_csr(void){
unsigned temp;
//Index = [(y * width) + x]
temp = csr_y * 80 + csr_x;
/* This sends a command to indicies 14 and 15 in the
* CRT Control Register of the VGA controller. These
* are the high and low bytes of the index that show
* where the hardware cursor is to be 'blinking'. To
* learn more, you should look up some VGA specific
* programming documents. A great start to graphics:
* http://www.brackeen.com/home/vga */
outportb(0x3D4, 14);
outportb(0x3D5, temp >> 8);
outportb(0x3D4, 15);
outportb(0x3D5, temp);
};
void cls(){
unsigned blank;
int i;
blank = 0x20 | (attrib << 8); //Blank character with black background
// Clear entire screen
for(i = 0; i < 25; i++)
memsetw (textmemptr + i * 80, blank, 80);
/* Update out virtual cursor, and then move the
* hardware cursor */
csr_x = 0;
csr_y = 0;
move_csr();
}
/* Puts a single character on the screen */
void putch(const char c){
unsigned short *where;
unsigned att = attrib << 8;
/* Handle a backspace, by moving the cursor back one space */
if(c == 0x08)
{
if(csr_x != 0) {
csr_x--;
putch(' ');
csr_x--;
};
}
/* Handles a tab by incrementing the cursor's x, but only
* to a point that will make it divisible by 8 */
else if(c == 0x09)
{
csr_x = (csr_x + 8) & ~(8 - 1);
}
/* Handles a 'Carriage Return', which simply brings the
* cursor back to the margin */
else if(c == '\r')
{
csr_x = 0;
}
/* We handle our newlines the way DOS and the BIOS do: we
* treat it as if a 'CR' was also there, so we bring the
* cursor to the margin and we increment the 'y' value */
else if(c == '\n')
{
csr_x = 0;
csr_y++;
}
/* Any character greater than and including a space, is a
* printable character. The equation for finding the index
* in a linear chunk of memory can be represented by:
* Index = [(y * width) + x] */
else if(c >= ' ')
{
where = textmemptr + (csr_y * 80 + csr_x);
*where = c | att; /* Character AND attributes: color */
csr_x++;
}
/* If the cursor has reached the edge of the screen's width, we
* insert a new line in there */
if(csr_x >= 80)
{
csr_x = 0;
csr_y++;
}
/* Scroll the screen if needed, and finally move the cursor */
scroll();
move_csr();
}
/* Uses the above routine to output a string... */
void puts(char *text){
int i;
for (i = 0; i < strlen(text); i++)
{
putch(text[i]);
}
}
/* Sets the forecolor and backcolor that we will use */
void settextcolor(unsigned char forecolor, unsigned char backcolor){
/* Top 4 bytes are the background, bottom 4 bytes
* are the foreground color */
attrib = (backcolor << 4) | (forecolor & 0x0F);
}
void init_video(void)
{
textmemptr = (unsigned short *)0xB8000;
cls();
}
void putint(unsigned num){
unsigned char counter=1;
unsigned int tmp=1;
while(num!=num%(10*tmp)){
counter++;
tmp*=10;
};
buffer[counter]='\0';
for(;counter>0;counter--){
buffer[counter-1]='0'+num%10;
num/=10;
};
puts(buffer);
};