Add vga_print_string.

This commit is contained in:
Alexander Myltsev 2022-11-14 00:23:42 +03:00
parent dbaad4cf88
commit d95ab832c3
5 changed files with 72 additions and 3 deletions

View File

@ -16,7 +16,7 @@ debug: image.bin
image.bin: mbr.bin kernel.bin image.bin: mbr.bin kernel.bin
cat $^ >$@ cat $^ >$@
kernel.bin: kernel.o kernel.bin: kernel.o vga.o
$(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary $(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary
%.o: %.c %.o: %.c

View File

@ -1,7 +1,9 @@
asm("jmp main"); asm("jmp main");
#include "vga.h"
int main() { int main() {
char* video_memory = (char*) 0xb8000; vga_clear_screen();
*video_memory = 'X'; vga_print_string("hello world");
return 0; return 0;
} }

11
port.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
static unsigned char port_byte_in(unsigned short port) {
unsigned char result;
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
return result;
}
static void port_byte_out(unsigned short port, unsigned char data) {
__asm__("out %%al, %%dx" : : "a" (data), "d" (port));
}

51
vga.c Normal file
View File

@ -0,0 +1,51 @@
#include "port.h"
char* const video_memory = (char*) 0xb8000;
enum {
LINES = 25,
COLS = 80,
WHITE_ON_BLACK = 0x0f,
VGA_CTRL_REGISTER = 0x3d4,
VGA_DATA_REGISTER = 0x3d5,
VGA_OFFSET_LOW = 0x0f,
VGA_OFFSET_HIGH = 0x0e,
};
void vga_set_cursor(unsigned offset) {
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_HIGH);
port_byte_out(VGA_DATA_REGISTER, (unsigned char) (offset >> 8));
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_LOW);
port_byte_out(VGA_DATA_REGISTER, (unsigned char) (offset & 0xff));
}
unsigned vga_get_cursor() {
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_HIGH);
unsigned offset = port_byte_in(VGA_DATA_REGISTER) << 8;
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_LOW);
offset += port_byte_in(VGA_DATA_REGISTER);
return offset;
}
void vga_set_char(unsigned offset, char c) {
video_memory[2 * offset] = c;
video_memory[2 * offset + 1] = WHITE_ON_BLACK;
}
void vga_clear_screen() {
for (unsigned i = 0; i < LINES * COLS; ++i) {
vga_set_char(i, ' ');
}
vga_set_cursor(0);
}
void vga_print_string(const char* s) {
int offset = vga_get_cursor();
while (*s != 0) {
vga_set_char(offset, *s);
s++;
offset++;
}
vga_set_cursor(offset);
}

5
vga.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void vga_clear_screen();
void vga_print_string(const char* s);