historical/gems-kernel.git/source/standard_io.h
2024-01-16 11:20:27 -06:00

218 lines
4.7 KiB
C

int x = 0;
int y = 0;
int lc = 0;
int VGA_WIDTH = 24;
char *line = 0x00;
void clear() {
char *mem = (char*)0xb8000;
int i = 0;
while (i < 4096) {
mem[i++] = 0;
}
}
/* We will use this later on for reading from the I/O ports to get data
* from devices such as the keyboard. We are using what is called
* 'inline assembly' in these routines to actually do the work */
unsigned char inportb (unsigned short _port)
{
unsigned char rv;
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
return rv;
}
/* We will use this to write to I/O ports to send bytes to devices. This
* will be used in the next tutorial for changing the textmode cursor
* position. Again, we use some inline assembly for the stuff that simply
* cannot be done in C */
void outportb (unsigned short _port, unsigned char _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
// This is the x86's VGA textmode buffer. To display text, we write data to this memory location
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000;
// By default, the VGA textmode buffer has a size of 80x25 characters
const int VGA_COLS = 80;
const int VGA_ROWS = 25;
// We start displaying text in the top-left of the screen (column = 0, row = 0)
int term_col = 0;
int term_row = 0;
uint8_t term_color = 0x0F; // Black background, White foreground
// This function initiates the terminal by clearing it
void term_init()
{
// Clear the textmode buffer
for (int col = 0; col < VGA_COLS; col ++)
{
for (int row = 0; row < VGA_ROWS; row ++)
{
// The VGA textmode buffer has size (VGA_COLS * VGA_ROWS).
// Given this, we find an index into the buffer for our character
const size_t index = (VGA_COLS * row) + col;
// Entries in the VGA buffer take the binary form BBBBFFFFCCCCCCCC, where:
// - B is the background color
// - F is the foreground color
// - C is the ASCII character
vga_buffer[index] = ((uint16_t)term_color << 8) | ' '; // Set the character to blank (a space character)
}
}
}
// This function places a single character onto the screen
void printc(char c)
{
// Remember - we don't want to display ALL characters!
switch (c)
{
case '\n': // Newline characters should return the column to 0, and increment the row
{
term_col = 0;
term_row ++;
break;
}
default: // Normal characters just get displayed and then increment the column
{
const size_t index = (VGA_COLS * term_row) + term_col; // Like before, calculate the buffer index
vga_buffer[index] = ((uint16_t)term_color << 8) | c;
term_col ++;
break;
}
}
// What happens if we get past the last column? We need to reset the column to 0, and increment the row to get to a new line
if (term_col >= VGA_COLS)
{
term_col = 0;
term_row ++;
}
// What happens if we get past the last row? We need to reset both column and row to 0 in order to loop back to the top of the screen
if (term_row >= VGA_ROWS)
{
term_col = 0;
term_row = 0;
}
}
// This function prints an entire string onto the screen
void print(const char* str)
{
if (str == 0x07) {
beep();
} else {
for (size_t i = 0; str[i] != '\0'; i ++) // Keep placing characters until we hit the null-terminating character ('\0')
printc(str[i]);
}
}
char int2str(int num) {
//convert int to string without common libraries
char str[10];
int i = 0;
while (num > 0) {
str[i] = num % 10 + '0';
num /= 10;
i++;
}
str[i] = '\0';
char *p = str;
while (*p != '\0') {
p++;
}
p--;
char c = *p;
*p = '\0';
return c;
}
void printint(int num)
{
char str = int2str(num); //Make number a string.
print(str); //print it.
}
//DO NOT USE
void vgaprint(char *text, int color) {
lc = color;
char *mem = (char*)0xb8000;
if (y == 23) {
clear(lc);
y = 0;
}
while (*text != 0) {
if (x > 78) {
int i = 0;
while (i < x){
mem[i++] = 0;
}
x = 0;
y = y + 1;
}
x = x + 1;
if (*text == "\n") {
int i = 0;
while (i < x) {
mem[i++] = 0;
}
x = 0;
y = y + 1;
} else {
*mem++ = *text++;
*mem++ = color;
}
int i = 0;
while (i < x) {
mem[i++] = 0;
}
x = 0;
y = y + 1;
}
}
int lastVGATextColor() {
return lc;
}
void setTermColor(uint8_t color) {
term_color = color;
}
uint8_t termColor() {
return term_color;
}
//create malloc function without standard libs
char malloc(int size) {
char *mem = (char*)0xb8000;
int i = 0;
while (i < size) {
mem[i++] = 0;
}
return (char)mem;
}
//create free function without standard libs
void free(char *mem) {
int i = 0;
while (mem[i] != 0) {
mem[i++] = 0;
}
}
void basickeys() {
register char *ptr asm("ax");; //pointer var
//do something
while(*ptr != '\0') {
*line = *ptr;
print(ptr); //try to print what's in memory
ptr++; //add 1 to ptr
}
}