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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <malloc.h>
#include "vesa.h"
void PutFont(char c, int x,int y, int color_fg,int color_bg);
#define VMEM_USER_FRAMEBUFFER 0xfc000000
// framebuffer info
static uint32_t vesaXres;
static uint32_t vesaYres;
static uint32_t vesaPitch;
static uint32_t vesaBpp;
static uint32_t vesaAddr;
// font
static uint8_t *foolfont;
static uint32_t font_width;
static uint32_t font_height;
// cursor position
static int console_x;
static int console_y;
//terminal size
static int console_lines;
static int console_cols;
static uint8_t termdata[80*24];
static uint8_t termdata_bg[80*24];
static uint8_t termdata_fg[80*24];
// same colors as in screen.h
static uint32_t cols[] = {
0x0, // black
0x0066cc, //blue
0x009900, //green
0x33ffff, //cyan
0xff3333, //red
0xcc00cc, //magenta
0x994c00, //brown
0xa0a0a0, //light gray
0x404040, //dark gray
0x3399ff, //light blue
0x99ff33, //light green
0x99ffff, //cyan light
0xff9999, //red light
0xff99ff, //magenta light
0xffff00, //yellow
0xffffff, //white
};
/** update cursor position */
void vesa_update_cursor(uint32_t col,uint32_t row)
{
int oldx=console_x;
int oldy=console_y;
console_x=col;
console_y=row;
vesa_console_put_char(termdata[oldy*80+oldx],termdata_bg[oldy*80+oldx],termdata_fg[oldy*80+oldx],oldx,oldy);
vesa_console_put_char(termdata[row*80+col],termdata_bg[row*80+col],termdata_fg[row*80+col],col,row);
}
/** put char */
void vesa_console_put_char(uint8_t c,uint8_t color_bg, uint8_t color_fg, uint32_t x, uint32_t y)
{
termdata[y*80+x]=c;
termdata_bg[y*80+x]=color_bg;
termdata_fg[y*80+x]=color_fg;
if(x==console_x&&y==console_y)PutFont(c, x,y, cols[color_fg],cols[color_bg]);
else PutFont(c, x,y, cols[color_bg],cols[color_fg]);
}
//
// We want to get output to the screen as fast as possible!
//
// Our Fool-Boot-Loader did set up VESA already for us.
// The desired VESA mode is hardcoded in [boot/mbr.asm].
//
// The [vesa_init(...)] function requires:
//
// * the addresses of the vbeinfo struct
// * the address of the vbemodeinfo struct (for selected mode).
// * Fool Font loaded inside ramimage
//
// The first two paramters are hardcoded in [boot/mbr.asm],
// while the last one is set in the Makefile. The font binary
// is integrated in the kernel image.
//
// this function returns the physical base address of
// our video memory
//
uint32_t vesa_init(char *fontname)
{
// LOAD FONT
FILE *f;
//if(fontname==NULL)f=fopen("/doc/fonts/binfont.bin","r");
//if(fontname==NULL)f=fopen("/doc/fonts/tinyfont.bin","r");
if(fontname==NULL)f=fopen("/doc/fonts/envypn7x13.bin","r");
fread(&font_width,1,1,f);
fread(&font_height,1,1,f);
int bits_per_font=font_width*font_height;
int alloc_bytes=(bits_per_font*95+7)/8;
foolfont=malloc(alloc_bytes);
fread(foolfont,1,alloc_bytes,f);
// virtual screen
vesaXres=640;
vesaYres=480;
vesaPitch=640*4;
vesaBpp=4; //32bit
vesaAddr=VMEM_USER_FRAMEBUFFER;
//
//
console_x=0;
console_y=0;
//TODO dynamic (but need to sync with terminal!)
console_cols=80;
console_lines=24;
return vesaAddr;
}
// TODO: what will happen in 24bit mode?
// TODO: optimize
void PutPixel(int x,int y, int color)
{
/*
//do not write memory outside the screen buffer, check parameters against the VBE mode info
if (x<0 || x>vesaXres|| y<0 || y>vesaYres) return;
if (x) x = (x*(vesaBpp>>3)); // get bytes (divide by 8)
if (y) y = (y*vesaPitch);
//uint8_t *cTemp=VbeModeInfoBlock->physbase;
uint8_t *cTemp=VMEM_USER_FRAMEBUFFER;
cTemp[x+y] = (uint8_t)(color & 0xff);
cTemp[x+y+1] = (uint8_t)((color>>8) & 0xff);
cTemp[x+y+2] = (uint8_t)((color>>16) & 0xff);
*/
uint8_t *p=VMEM_USER_FRAMEBUFFER+y*vesaPitch+x*vesaBpp;
uint32_t *pix=p;
*pix=color;
}
static bool check_pixel(int idx,int x,int y)
{
// x=font_width-x-1;
int pixel_index=idx*font_width*font_height+y*font_width+x;
return foolfont[pixel_index/8]&(1<<(7-(pixel_index%8)));
}
/**
* Put character C in column X of row Y using colors fg and bg
*/
void PutFont(char c, int x,int y, int color_fg,int color_bg)
{
int fnt;
if(c>=0x20&&c<=0x126)fnt=c-0x20;
else return; // any other fonts??
//x=x*(1+font_width);
//y=y*(1+font_height);
x=x*(font_width+1);
y=y*(font_height+1);
//fill broder with bg color
for(int posx=x;posx<x+font_width+1;posx++)PutPixel(posx,y+font_height,color_bg);
for(int posy=y;posy<y+font_height;posy++)PutPixel(x+font_width,posy,color_bg);
// paint letter
for(int posx=x;posx<x+font_width;posx++)
{
for(int posy=y;posy<y+font_height;posy++)
{
//if(deffont[fnt].line[posy-y]&1<<(7-(posx-x)))
if(check_pixel(fnt,posx-x,posy-y))PutPixel(posx,posy,color_fg);
else PutPixel(posx,posy,color_bg);
}
}
/*
for(int y=0;y<vesaYres;y++)
{
PutPixel(0,y,0xff);
PutPixel(100,y,0xff);
PutPixel(vesaXres-1,y,0xff);
}
for(int x=0;x<vesaXres;x++)
{
PutPixel(x,0,0xff);
PutPixel(x,100,0xff);
PutPixel(x,vesaYres-1,0xff);
}
*/
}
|