Moved i/o content to kerno.c
Added function for integer -> string (library pending) Modified makefile to reflect use of include/ dir
This commit is contained in:
parent
5dd086565f
commit
5efb8d9fbc
4 changed files with 132 additions and 56 deletions
14
Makefile
14
Makefile
|
|
@ -5,9 +5,9 @@ AS := $(CROSS)as
|
||||||
CC := $(CROSS)gcc
|
CC := $(CROSS)gcc
|
||||||
LD := $(CROSS)ld
|
LD := $(CROSS)ld
|
||||||
QEMU := qemu-system-i386
|
QEMU := qemu-system-i386
|
||||||
|
INCLUDES:= include/
|
||||||
|
|
||||||
|
CFLAGS := -I $(INCLUDES) -O2 -Wall -Wextra -ffreestanding -nostdlib -lgcc -g
|
||||||
CFLAGS := -ffreestanding -nostdlib -lgcc -g
|
|
||||||
LDFLAGS := -T linker.ld -nostdlib
|
LDFLAGS := -T linker.ld -nostdlib
|
||||||
|
|
||||||
SRC_DIR := src
|
SRC_DIR := src
|
||||||
|
|
@ -58,9 +58,17 @@ clean:
|
||||||
iso: $(OUT_ISO)
|
iso: $(OUT_ISO)
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run:
|
run: $(OUT_ELF)
|
||||||
$(QEMU) -kernel $(OUT_ELF)
|
$(QEMU) -kernel $(OUT_ELF)
|
||||||
|
|
||||||
|
.PHONY: debug
|
||||||
|
debug:
|
||||||
|
$(QEMU) -s -S -kernel $(OUT_ELF)
|
||||||
|
|
||||||
.PHONY: run_iso
|
.PHONY: run_iso
|
||||||
run_iso:
|
run_iso:
|
||||||
$(QEMU) -cdrom $(OUT_ISO)
|
$(QEMU) -cdrom $(OUT_ISO)
|
||||||
|
|
||||||
|
.PHONY: debug_iso
|
||||||
|
debug_iso:
|
||||||
|
$(QEMU) -s -S -cdrom $(OUT_ISO)
|
||||||
|
|
|
||||||
35
include/kernio.h
Normal file
35
include/kernio.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef KERNIO_H
|
||||||
|
#define KERNIO_H
|
||||||
|
#define VGA_GRID_COLS 79
|
||||||
|
#define VGA_GRID_ROWS 25
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CONSTANTS AND VARIABLES
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Information on the VGA buffer
|
||||||
|
|
||||||
|
extern volatile uint16_t* const vga_buffer;
|
||||||
|
|
||||||
|
//grid is top left origin. This is our cursor!
|
||||||
|
extern int cursor_col;
|
||||||
|
extern int cursor_row;
|
||||||
|
extern uint16_t vga_attributes; // Black background, White foreground
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Clear the VGA buffer
|
||||||
|
void vga_clear();
|
||||||
|
//Put a character in the VGA buffer and move the cursor to the right by one
|
||||||
|
void vga_putc(char c);
|
||||||
|
void vga_set_attributes(uint8_t attributes);
|
||||||
|
void vga_print(const char* out);
|
||||||
|
void vga_println(const char* out);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
57
src/kernio.c
Normal file
57
src/kernio.c
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "kernio.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VARS
|
||||||
|
*/
|
||||||
|
|
||||||
|
int cursor_col = 0;
|
||||||
|
int cursor_row = 0;
|
||||||
|
volatile uint16_t* const vga_buffer = (uint16_t*)0xB8000;
|
||||||
|
uint16_t vga_attributes = 0x0F00;
|
||||||
|
|
||||||
|
void vga_clear() {
|
||||||
|
for (int col = 0; col < VGA_GRID_COLS; col ++) {
|
||||||
|
for (int row = 0; row < VGA_GRID_ROWS; row ++) {
|
||||||
|
//works out to iterating every cell
|
||||||
|
const size_t index = (VGA_GRID_COLS * row) + col;
|
||||||
|
//vga buffer looks something like xxxxyyyyzzzzzzzz
|
||||||
|
//x=bg color
|
||||||
|
//y=fg color
|
||||||
|
//c=character to use
|
||||||
|
//Therefore, to write, we just take our color data and tack on the character to the end.
|
||||||
|
vga_buffer[index] = vga_attributes | ' '; //blank out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_putc(char c)
|
||||||
|
{
|
||||||
|
//Check for some freaky escape character first
|
||||||
|
if(c == '\n') {
|
||||||
|
cursor_col = 0;
|
||||||
|
cursor_row = (cursor_row + 1) % 25;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Calculate where in the vga buffer to put the character
|
||||||
|
const size_t index = (VGA_GRID_COLS * cursor_row) + cursor_col;
|
||||||
|
//VGA buffer cell consists of the first half attributes, second half character
|
||||||
|
vga_buffer[index] = vga_attributes | c;
|
||||||
|
cursor_col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_attributes(uint8_t attributes) {
|
||||||
|
vga_attributes = ((uint16_t)attributes) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vga_print(const char* out)
|
||||||
|
{
|
||||||
|
for (int i = 0; out[i] != '\0'; i++)
|
||||||
|
vga_putc(out[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_println(const char* out) {
|
||||||
|
vga_print(out);
|
||||||
|
vga_print("\n");
|
||||||
|
}
|
||||||
76
src/main.c
76
src/main.c
|
|
@ -1,55 +1,30 @@
|
||||||
// Reworked sample code from OSDev! Stripped down some of the extra stuff to leave as an exercise.
|
//Our own code, at this point...
|
||||||
//Headers provided by GCC :). No need for libs! We don't even have those yet.
|
//#include <stddef.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "kernio.h"
|
||||||
|
|
||||||
|
//convert digits from int num to buffer buf. in hex. This is 32 bit only for now!
|
||||||
//VGA buffer is the easiest way to write to the screen at this stage. it's just a massive array with two datapoints: what color, and what character?
|
//WARN: integer is written from right to left into the buffer, and will halt if the buffer is too small.
|
||||||
//array starts at the absolute address 0xB8000
|
void i_to_str(uint32_t num, char* buf, int size) {
|
||||||
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000;
|
//null terminate the string
|
||||||
//the VGA buffer is 80x25 to represent the screen.
|
buf[--size] = '\0';
|
||||||
const int GRID_COLS = 80;
|
while(size > 0 && (num) != 0){
|
||||||
const int GRID_ROWS = 25;
|
int isolated_num = num % 0x10;
|
||||||
|
if(isolated_num > 9){
|
||||||
|
isolated_num+=7;
|
||||||
//grid is top left origin. This is our cursor!
|
|
||||||
int cursor_col = 0;
|
|
||||||
int cursor_row = 0;
|
|
||||||
uint16_t term_color = 0x0F00; // Black background, White foreground
|
|
||||||
|
|
||||||
|
|
||||||
//wipe the screen
|
|
||||||
void term_clear() {
|
|
||||||
for (int col = 0; col < GRID_COLS; col ++) {
|
|
||||||
for (int row = 0; row < GRID_ROWS; row ++) {
|
|
||||||
//works out to iterating every cell
|
|
||||||
const size_t index = (GRID_COLS * row) + col;
|
|
||||||
//vga buffer looks something like xxxxyyyyzzzzzzzz
|
|
||||||
//x=bg color
|
|
||||||
//y=fg color
|
|
||||||
//c=character to use
|
|
||||||
//Therefore, to write, we just take our color data and tack on the character to the end.
|
|
||||||
vga_buffer[index] = term_color | ' '; //blank out
|
|
||||||
}
|
}
|
||||||
|
buf[--size] = '0' + isolated_num;
|
||||||
|
num/=0x10;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//now shift the whole thing to the left
|
||||||
void term_printc(char c)
|
if(size != 0) {
|
||||||
{
|
while(buf[size]!='\0') {
|
||||||
const size_t index = (GRID_COLS * cursor_row) + cursor_col; //where am i puttin it
|
*buf = buf[size];
|
||||||
vga_buffer[index] = term_color | c; //put it there by putting color+char into that spot in the array
|
buf++;
|
||||||
cursor_col++; //next time put it in the next spot.
|
}
|
||||||
}
|
*buf = '\0';
|
||||||
|
}
|
||||||
//print a string!
|
|
||||||
void term_println(const char* out)
|
|
||||||
{
|
|
||||||
for (int i = 0; out[i] != '\0'; i++)
|
|
||||||
term_printc(out[i]);
|
|
||||||
//go to the next line for a println func.
|
|
||||||
cursor_col = 0;
|
|
||||||
cursor_row++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -58,10 +33,11 @@ void kern_main()
|
||||||
{
|
{
|
||||||
|
|
||||||
//wipe the screen
|
//wipe the screen
|
||||||
term_clear();
|
vga_clear();
|
||||||
|
|
||||||
//IT IS TIME. TO PRINT.
|
//IT IS TIME. TO PRINT.
|
||||||
term_println("hello my chungus world");
|
char lol[5];
|
||||||
term_println(":100:");
|
i_to_str(0xCAFEBABE, lol, 5);
|
||||||
|
vga_println(lol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue