réplica de
https://github.com/Arnau478/quark.git
synced 2024-11-27 06:08:05 +01:00
Finished VGA driver and implemented stdio.h (printf and puts)
This commit is contained in:
pare
deae8de0d5
commit
2160a41e81
S'han modificat 5 arxius amb 123 adicions i 22 eliminacions
|
@ -3,22 +3,22 @@
|
||||||
|
|
||||||
static uint8_t current_color = VGA_COLOR_DEFAULT;
|
static uint8_t current_color = VGA_COLOR_DEFAULT;
|
||||||
|
|
||||||
void set_char(int x, int y, char c){
|
void vga_set_char(int x, int y, char c){
|
||||||
VGA_MEMORY[(x+y*VGA_WIDTH)*2] = c;
|
VGA_MEMORY[(x+y*VGA_WIDTH)*2] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_color(int x, int y, uint8_t color){
|
void vga_set_color(int x, int y, uint8_t color){
|
||||||
VGA_MEMORY[(x+y*VGA_WIDTH)*2+1] = color;
|
VGA_MEMORY[(x+y*VGA_WIDTH)*2+1] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_cursor(int offset){
|
void vga_set_cursor(int offset){
|
||||||
i686_outb(VGA_PORT_CTRL, 14);
|
i686_outb(VGA_PORT_CTRL, 14);
|
||||||
i686_outb(VGA_PORT_DATA, (uint8_t)(offset >> 8));
|
i686_outb(VGA_PORT_DATA, (uint8_t)(offset >> 8));
|
||||||
i686_outb(VGA_PORT_CTRL, 15);
|
i686_outb(VGA_PORT_CTRL, 15);
|
||||||
i686_outb(VGA_PORT_DATA, (uint8_t)(offset & 0xff));
|
i686_outb(VGA_PORT_DATA, (uint8_t)(offset & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_cursor(){
|
int vga_get_cursor(){
|
||||||
i686_outb(VGA_PORT_CTRL, 14);
|
i686_outb(VGA_PORT_CTRL, 14);
|
||||||
int offset = i686_inb(VGA_PORT_DATA) << 8; // High byte
|
int offset = i686_inb(VGA_PORT_DATA) << 8; // High byte
|
||||||
i686_outb(VGA_PORT_CTRL, 15);
|
i686_outb(VGA_PORT_CTRL, 15);
|
||||||
|
@ -34,7 +34,7 @@ static int get_offset_x(int offset){
|
||||||
return (offset - (get_offset_y(offset)*VGA_WIDTH));
|
return (offset - (get_offset_y(offset)*VGA_WIDTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_char(char c, int x, int y){
|
int vga_print_char(char c, int x, int y){
|
||||||
if(x >= VGA_WIDTH || y >= VGA_HEIGHT){ // Incorrect coords
|
if(x >= VGA_WIDTH || y >= VGA_HEIGHT){ // Incorrect coords
|
||||||
VGA_MEMORY[2*VGA_WIDTH*VGA_HEIGHT-2] = 'E';
|
VGA_MEMORY[2*VGA_WIDTH*VGA_HEIGHT-2] = 'E';
|
||||||
VGA_MEMORY[2*VGA_WIDTH*VGA_HEIGHT-1] = VGA_COLOR_BG_RED || VGA_COLOR_FG_BLACK;
|
VGA_MEMORY[2*VGA_WIDTH*VGA_HEIGHT-1] = VGA_COLOR_BG_RED || VGA_COLOR_FG_BLACK;
|
||||||
|
@ -43,7 +43,7 @@ int print_char(char c, int x, int y){
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
if(x >= 0 && y >= 0) offset = y*VGA_WIDTH+x;
|
if(x >= 0 && y >= 0) offset = y*VGA_WIDTH+x;
|
||||||
else offset = get_cursor();
|
else offset = vga_get_cursor();
|
||||||
|
|
||||||
if(c == '\n'){
|
if(c == '\n'){
|
||||||
y = get_offset_y(offset);
|
y = get_offset_y(offset);
|
||||||
|
@ -61,17 +61,17 @@ int print_char(char c, int x, int y){
|
||||||
|
|
||||||
// TODO: Scroll
|
// TODO: Scroll
|
||||||
|
|
||||||
set_cursor(offset);
|
vga_set_cursor(offset);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void puts_at(char *str, int x, int y){
|
void vga_print_string_at(char *str, int x, int y){
|
||||||
int offset;
|
int offset;
|
||||||
if(x >= 0 && y >= 0){
|
if(x >= 0 && y >= 0){
|
||||||
offset = y*VGA_WIDTH+x;
|
offset = y*VGA_WIDTH+x;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
offset = get_cursor();
|
offset = vga_get_cursor();
|
||||||
x = get_offset_x(offset);
|
x = get_offset_x(offset);
|
||||||
y = get_offset_y(offset);
|
y = get_offset_y(offset);
|
||||||
}
|
}
|
||||||
|
@ -105,13 +105,13 @@ void puts_at(char *str, int x, int y){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
offset = print_char(*(str++), x, y);
|
offset = vga_print_char(*(str++), x, y);
|
||||||
x = get_offset_x(offset);
|
x = get_offset_x(offset);
|
||||||
y = get_offset_y(offset);
|
y = get_offset_y(offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void puts(char *str){
|
void vga_print_string(char *str){
|
||||||
puts_at(str, -1, -1);
|
vga_print_string_at(str, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
#define VGA_PORT_CTRL 0x3D4
|
#define VGA_PORT_CTRL 0x3D4
|
||||||
#define VGA_PORT_DATA 0x3D5
|
#define VGA_PORT_DATA 0x3D5
|
||||||
|
|
||||||
void set_char(int x, int y, char c);
|
void vga_set_char(int x, int y, char c);
|
||||||
void set_color(int x, int y, uint8_t color);
|
void vga_set_color(int x, int y, uint8_t color);
|
||||||
void set_cursor(int offset);
|
void vga_set_cursor(int offset);
|
||||||
int get_cursor();
|
int vga_get_cursor();
|
||||||
int print_char(char c, int x, int y);
|
int vga_print_char(char c, int x, int y);
|
||||||
void puts_at(char *str, int x, int y);
|
void vga_print_string_at(char *str, int x, int y);
|
||||||
void puts(char *str);
|
void vga_print_string(char *str);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
|
||||||
void __attribute__((cdecl)) kmain(uint64_t magic, uint64_t addr){
|
void __attribute__((cdecl)) kmain(uint64_t magic, uint64_t addr){
|
||||||
printf("Hello world!\n\x1b[32m:D\x1b[0m\n");
|
puts("\x1b[33mWARNING\x1b[0m");
|
||||||
|
printf(": amazing %s ahead!\n", "math");
|
||||||
|
printf("%i+%i=%i\n", 1, 1, 2);
|
||||||
for(;;); // Halt here
|
for(;;); // Halt here
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,103 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "drivers/vga.h"
|
#include "drivers/vga.h"
|
||||||
|
|
||||||
void printf(char *fmt, ...){
|
static char g_HexChars[] = "0123456789abcdef";
|
||||||
puts(fmt);
|
|
||||||
|
void puts(char *str){
|
||||||
|
vga_print_string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void putc(char c){
|
||||||
|
char str[2];
|
||||||
|
str[0] = c;
|
||||||
|
str[1] = '\0';
|
||||||
|
vga_print_string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printf_signed(unsigned long long num, int radix){
|
||||||
|
char buffer[32];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
// Convert to ASCII
|
||||||
|
do{
|
||||||
|
unsigned long long rem = num % radix;
|
||||||
|
num /= radix;
|
||||||
|
buffer[pos++] = g_HexChars[rem];
|
||||||
|
} while(num > 0);
|
||||||
|
|
||||||
|
while(--pos >= 0) putc(buffer[pos]); // Note reverse order
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printf_unsigned(unsigned long long num, int radix){
|
||||||
|
if(num < 0){
|
||||||
|
putc('-');
|
||||||
|
printf_unsigned(-num, radix);
|
||||||
|
}
|
||||||
|
else printf_unsigned(num, radix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printf(char *fmt, ...){
|
||||||
|
// Variadic function arguments
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
while(*fmt){
|
||||||
|
if(*fmt == '%'){
|
||||||
|
bool number = false;
|
||||||
|
bool sign = false;
|
||||||
|
int radix = 10;
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
switch(*fmt){
|
||||||
|
case '%':
|
||||||
|
putc('%');
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
putc((char)va_arg(args, int));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
puts(va_arg(args, char *));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
number = true;
|
||||||
|
radix = 10;
|
||||||
|
sign = true;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
number = true;
|
||||||
|
radix = 10;
|
||||||
|
sign = false;
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
case 'x':
|
||||||
|
case 'p':
|
||||||
|
number = true;
|
||||||
|
radix = 16;
|
||||||
|
sign = false;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
number = true;
|
||||||
|
radix = 8;
|
||||||
|
sign = false;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement length modifiers
|
||||||
|
if(number){
|
||||||
|
if(sign){
|
||||||
|
printf_signed(va_arg(args, int), radix);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
printf_unsigned(va_arg(args, unsigned int), radix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
else putc(*(fmt++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
void puts(char *str);
|
||||||
|
void putc(char c);
|
||||||
void printf(char *fmt, ...);
|
void printf(char *fmt, ...);
|
||||||
|
|
Loading…
Referencia en una nova incidència