Moved some files around in preparation for completely changing the way that booting works
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#include "atapio.h"
|
||||
|
||||
// Disk code
|
||||
|
||||
// Primary ATA Bus: 0x1f0 to 0x1f7
|
||||
// Device Control Register: 0x3f6
|
||||
// Secondary ATA Bus: 0x170 to 0x177
|
||||
// Device Control Register: 0x376
|
||||
|
||||
|
||||
uint16_t identify_result[256];
|
||||
uint32_t total_28_lbas = 0;
|
||||
|
||||
uint8_t* rootDirEntries = 0x1000000;
|
||||
uint16_t* FAT1 = 0x1002000;
|
||||
|
||||
uint16_t countReserved;
|
||||
uint8_t countFATs;
|
||||
uint16_t countRDEs;
|
||||
uint16_t sectorsPerFAT;
|
||||
|
||||
|
||||
void init_atapio() {
|
||||
countReserved = *(uint16_t*)0x7c0e;
|
||||
countFATs = *(uint8_t*)0x7c10;
|
||||
countRDEs = *(uint16_t*)0x7c11;
|
||||
sectorsPerFAT = *(uint16_t*)0x7c16;
|
||||
|
||||
// Select Drive 0 on the Primary Bus
|
||||
outb(0x1f6, 0xa0);
|
||||
|
||||
// Set sector count to 0 for IDENTIFY
|
||||
outb(0x1f2, 0);
|
||||
// Set LBAlo to 0
|
||||
outb(0x1f3, 0);
|
||||
// Set LBAmid to 0
|
||||
outb(0x1f4, 0);
|
||||
// Set LBAhi to 0
|
||||
outb(0x1f5, 0);
|
||||
|
||||
// Send IDENTIFY command
|
||||
outb(0x1f7, 0xec);
|
||||
|
||||
uint8_t status = inb(0x1f7);
|
||||
if (status) {
|
||||
while ((status = inb(0x1f7)) & 0x80);
|
||||
|
||||
if ( !(inb(0x1f4) || inb(0x1f5)) ) {
|
||||
while ( !(status & 8 || status & 1) )
|
||||
status = inb(0x1f7);
|
||||
|
||||
if (!(status & 1)) {
|
||||
for (int index=0; index<256; index++)
|
||||
identify_result[index] = inw(0x1f0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total_28_lbas = *(uint32_t*)(identify_result+60);
|
||||
|
||||
// We've initialised now, let's load the FAT and RootDirEntries.
|
||||
read_sectors(sectorsPerFAT * countFATs + 1, countRDEs / 16, rootDirEntries);
|
||||
read_sectors(1, sectorsPerFAT, FAT1);
|
||||
}
|
||||
|
||||
void read_sector(uint32_t address, uint8_t* buffer) {
|
||||
outb(0x1f6, 0xe0 | ((address>>24)&0x0f));
|
||||
// Read a single sector
|
||||
outb(0x1f2, 1);
|
||||
// Set LBAlo, LBAmid and LBAhi
|
||||
outb(0x1f3, address);
|
||||
outb(0x1f4, address>>8);
|
||||
outb(0x1f5, address>>16);
|
||||
|
||||
// Send read command
|
||||
outb(0x1f7, 0x20);
|
||||
// Poll
|
||||
uint8_t status = inb(0x1f7);
|
||||
while ( (status & 0x80) && !(status & 8) )
|
||||
status = inb(0x1f7);
|
||||
|
||||
for (int index=0; index<256; index++)
|
||||
((uint16_t*)buffer)[index] = inw(0x1f0);
|
||||
}
|
||||
|
||||
void read_sectors(uint32_t address, int count, uint8_t* buffer) {
|
||||
for (int i=0; i<count; i++) {
|
||||
read_sector(address+i, buffer+512*i);
|
||||
for (int i=0; i<15; i++)
|
||||
inb(0x1f7);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t file_exists(char* filename) {
|
||||
for (int i=0; i<countRDEs; i++) {
|
||||
bool found = strcmp(rootDirEntries+(i*32), filename, 11);
|
||||
if (found) {
|
||||
uint16_t* correctEntry = (rootDirEntries+(i*32));
|
||||
return correctEntry[13];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_file(char* filename, uint8_t* destination) {
|
||||
uint16_t location = file_exists(filename);
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
bool loaded = false;
|
||||
while (!loaded) {
|
||||
uint16_t fromSector = location + (sectorsPerFAT * countFATs) + (countRDEs / 16) - 1;
|
||||
read_sector(fromSector, destination+offset);
|
||||
offset += 512;
|
||||
|
||||
location = FAT1[location++];
|
||||
if (location == 0xffff)
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef ATA_PIO
|
||||
#define ATA_PIO
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "types.h"
|
||||
#include "strings.h"
|
||||
#include "screenstuff.h"
|
||||
|
||||
void init_atapio();
|
||||
void read_sector(uint32_t address, uint8_t* buffer);
|
||||
void read_sectors(uint32_t address, int count, uint8_t* buffer);
|
||||
uint16_t file_exists(char* filename);
|
||||
void load_file(char* filename, uint8_t* location);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "idt.h"
|
||||
|
||||
GateEntry idt[256];
|
||||
|
||||
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type) {
|
||||
uint32_t handler_addr = (uint16_t)handler;
|
||||
uint16_t* handler_halves = (uint16_t*)&handler_addr;
|
||||
idt[interrupt_number] = (GateEntry){
|
||||
.offset_low = handler_halves[0],
|
||||
.selector = code_segment,
|
||||
.zero = 0,
|
||||
.type = type,
|
||||
.offset_high = handler_halves[1]
|
||||
};
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void interrupt_20(struct interrupt_frame* frame) {
|
||||
// printf("Interrupt 20 received!!\n");
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void ignore_interrupt(struct interrupt_frame* frame) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void init_idt() {
|
||||
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
||||
asm volatile("lidt %0" : : "m" (desc));
|
||||
for (int i=0; i<256; i++)
|
||||
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
|
||||
|
||||
set_entry(0x20, 0x08, &interrupt_20, 0x8E);
|
||||
|
||||
outb(0x20, 0x11);
|
||||
outb(0xA0, 0x11);
|
||||
outb(0x21, 0x20);
|
||||
outb(0xA1, 0x28);
|
||||
outb(0x21, 0x04);
|
||||
outb(0xA1, 0x02);
|
||||
outb(0x21, 0x01);
|
||||
outb(0xA1, 0x01);
|
||||
outb(0x21, 0x00);
|
||||
outb(0xA1, 0x00);
|
||||
}
|
||||
|
||||
void enable_idt() {
|
||||
asm ("sti");
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include "types.h"
|
||||
#include "screenstuff.h"
|
||||
|
||||
struct interrupt_frame{
|
||||
uint16_t ip;
|
||||
uint16_t cs;
|
||||
uint16_t flags;
|
||||
uint16_t sp;
|
||||
uint16_t ss;
|
||||
};
|
||||
extern void load_idt();
|
||||
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type);
|
||||
void init_idt();
|
||||
void enable_idt();
|
||||
|
||||
typedef struct {
|
||||
uint16_t offset_low;
|
||||
uint16_t selector;
|
||||
uint8_t zero;
|
||||
uint8_t type;
|
||||
uint16_t offset_high;
|
||||
}__attribute__((packed)) GateEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t size;
|
||||
uint32_t offset;
|
||||
}__attribute__((packed)) idt_desc;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "io.h"
|
||||
|
||||
void outb(uint16_t portnumber, uint8_t data) {
|
||||
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint8_t inb(uint16_t portnumber) {
|
||||
uint8_t result;
|
||||
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
}
|
||||
|
||||
void outw(uint16_t portnumber, uint16_t data) {
|
||||
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint16_t inw(uint16_t portnumber) {
|
||||
uint16_t result;
|
||||
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void outb(uint16_t portnumber, uint8_t data);
|
||||
uint8_t inb(uint16_t portnumber);
|
||||
|
||||
void outw(uint16_t portnumber, uint16_t data);
|
||||
uint16_t inw(uint16_t portnumber);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "types.h"
|
||||
#include "screenstuff.h"
|
||||
#include "io.h"
|
||||
#include "idt.h"
|
||||
#include "keyboard.h"
|
||||
#include "strings.h"
|
||||
#include "atapio.h"
|
||||
|
||||
int main() {
|
||||
init_idt();
|
||||
init_term();
|
||||
|
||||
printf("KERNEL32 OK!\n");
|
||||
|
||||
printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n");
|
||||
|
||||
init_keyboard();
|
||||
enable_idt();
|
||||
init_atapio();
|
||||
|
||||
uint8_t sector[512];
|
||||
|
||||
read_sector(0, sector);
|
||||
|
||||
printf("OEM ID: %s\n", (char*)(sector+0x3));
|
||||
|
||||
char hellotxt[1024];
|
||||
|
||||
load_file("HELLO TXT", hellotxt);
|
||||
printf("%s", hellotxt);
|
||||
|
||||
|
||||
while (1) {
|
||||
printf(">>> ");
|
||||
char buffer[128];
|
||||
for (int i=0; i<128; i++)
|
||||
buffer[i] = 0;
|
||||
readline(128, buffer);
|
||||
|
||||
char* rest = split_on_first(' ', buffer);
|
||||
|
||||
|
||||
if (strcmp(buffer, "help", 4)) {
|
||||
printf(
|
||||
"XnoeOS 32 Bit Mode Help.\n"
|
||||
"------------------------\n"
|
||||
" - help\n"
|
||||
" : Shows this message\n"
|
||||
" - clear\n"
|
||||
" : Clears the screen\n"
|
||||
" - echo\n"
|
||||
" : Repeats the text written afterwards\n"
|
||||
);
|
||||
} else if (strcmp(buffer, "clear", 5)) {
|
||||
clear_screen();
|
||||
set_curpos(0, 0);
|
||||
} else if (strcmp(buffer, "echo", 4)) {
|
||||
printf("%s\n", rest);
|
||||
} else if (strcmp(buffer, "type", 4)) {
|
||||
char filenamebuffer[12];
|
||||
uint8_t* filebuffer = 0x1006400;
|
||||
|
||||
decode_filename(rest, filenamebuffer);
|
||||
if (!file_exists(filenamebuffer)) {
|
||||
printf("File %s not found!\n", filenamebuffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i=0; i<1024; i++)
|
||||
hellotxt[i] = 0;
|
||||
|
||||
load_file(filenamebuffer, filebuffer);
|
||||
printf(filebuffer);
|
||||
} else {
|
||||
char filenamebuffer[12];
|
||||
decode_filename(buffer, filenamebuffer);
|
||||
if (!file_exists(filenamebuffer)) {
|
||||
printf("Bad Command or filename!\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
[BITS 32]
|
||||
|
||||
_start:
|
||||
mov ax, 10h
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov esp, 90000h
|
||||
|
||||
call main
|
||||
|
||||
extern main
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "keyboard.h"
|
||||
|
||||
char key_to_char[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
|
||||
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
char key_to_char_caps[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\',
|
||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
char key_to_char_shift[128] = {
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|',
|
||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
uint8_t current_scancode = 0;
|
||||
|
||||
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) {
|
||||
current_scancode = inb(0x60);
|
||||
outb(0x20, 0x21);
|
||||
}
|
||||
|
||||
void init_keyboard() {
|
||||
set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E);
|
||||
|
||||
while (inb(0x64) & 1) {
|
||||
inb(0x60);
|
||||
}
|
||||
|
||||
outb(0x64, 0xAE);
|
||||
outb(0x64, 0x20);
|
||||
uint8_t keyboard_status = (inb(0x60) | 1) & ~0x10;
|
||||
outb(0x64, 0x60);
|
||||
outb(0x60, keyboard_status);
|
||||
outb(0x60, 0xF4);
|
||||
}
|
||||
|
||||
bool caps_on = false;
|
||||
bool shift_on = false;
|
||||
|
||||
void readline(int max, char* buffer) {
|
||||
int index = 0;
|
||||
|
||||
|
||||
uint8_t scancode = 0;
|
||||
while (scancode != 0x1c && index < max) {
|
||||
scancode = current_scancode;
|
||||
|
||||
char decoded = 0;
|
||||
|
||||
if ((scancode&0x7f) == 0x2a)
|
||||
shift_on = !(scancode&0x80);
|
||||
|
||||
if (scancode == 0x3a)
|
||||
caps_on ^= 1;
|
||||
|
||||
if (scancode == 0x0e && index > 0) {
|
||||
set_curpos_raw(get_curpos()-1);
|
||||
non_moving_put(' ');
|
||||
buffer[--index] = 0;
|
||||
}
|
||||
|
||||
if (shift_on)
|
||||
decoded = key_to_char_shift[scancode&0x7f];
|
||||
else if (caps_on)
|
||||
decoded = key_to_char_caps[scancode&0x7f];
|
||||
else
|
||||
decoded = key_to_char[scancode&0x7f];
|
||||
|
||||
if (decoded && scancode < 0x80) {
|
||||
buffer[index++] = decoded;
|
||||
printf("%c", decoded);
|
||||
}
|
||||
|
||||
while (scancode == current_scancode);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef KEYBOARD_H
|
||||
#define KEYBOARD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "io.h"
|
||||
#include "screenstuff.h"
|
||||
#include "idt.h"
|
||||
|
||||
void init_keyboard();
|
||||
void readline(int max, char* buffer);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
#include "screenstuff.h"
|
||||
|
||||
uint16_t* VMEM_ADDR = (uint16_t*)0xb8000;
|
||||
const int TERM_WIDTH = 80;
|
||||
const int TERM_HEIGHT = 25;
|
||||
|
||||
int cursor_x = 0;
|
||||
int cursor_y = 0;
|
||||
|
||||
uint16_t get_curpos() {
|
||||
uint16_t cursor_position = 0;
|
||||
uint8_t* cursor_position_split = (uint8_t*)&cursor_position;
|
||||
outb(0x3D4, 0x0F);
|
||||
cursor_position_split[0] = inb(0x3D5);
|
||||
outb(0x3D4, 0x0E);
|
||||
cursor_position_split[1] = inb(0x3D5);
|
||||
return cursor_position;
|
||||
}
|
||||
|
||||
void init_term() {
|
||||
uint16_t cursor_position = get_curpos();
|
||||
|
||||
cursor_y = cursor_position / TERM_WIDTH;
|
||||
cursor_x = cursor_position % TERM_WIDTH;
|
||||
}
|
||||
|
||||
void clear_screen() {
|
||||
for (int i=0; i<TERM_WIDTH*TERM_HEIGHT; i++) {
|
||||
VMEM_ADDR[i] = 0x0720;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_line(int line) {
|
||||
for (int x=0; x<TERM_WIDTH; x++) {
|
||||
VMEM_ADDR[TERM_WIDTH*line + x] = 0x0720;
|
||||
}
|
||||
}
|
||||
|
||||
void set_curpos_raw(int curpos) {
|
||||
uint8_t* cursor_position_split = (uint8_t*)&curpos;
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, cursor_position_split[0]);
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, cursor_position_split[1]);
|
||||
|
||||
cursor_x = (*(uint16_t*)cursor_position_split) % TERM_WIDTH;
|
||||
cursor_y = (*(uint16_t*)cursor_position_split) / TERM_WIDTH;
|
||||
}
|
||||
|
||||
void set_curpos(int x, int y) {
|
||||
set_curpos_raw(y * TERM_WIDTH + x);
|
||||
|
||||
cursor_x = x;
|
||||
cursor_y = y;
|
||||
}
|
||||
|
||||
int int_to_decimal(unsigned int number, char* string_buffer) {
|
||||
for (int i=0; i<11; i++)
|
||||
string_buffer[i] = 0;
|
||||
|
||||
int index = 9;
|
||||
unsigned int acc = number;
|
||||
if (acc == 0)
|
||||
string_buffer[index--] = '0';
|
||||
while (acc != 0) {
|
||||
string_buffer[index--] = 0x30+(acc%10);
|
||||
acc /= 10;
|
||||
}
|
||||
return (index+1);
|
||||
}
|
||||
|
||||
char dec_to_hex[16] = "0123456789abcdef";
|
||||
int int_to_hex(unsigned int number, char* string_buffer) {
|
||||
for (int i=0; i<9; i++)
|
||||
string_buffer[i] = 0;
|
||||
|
||||
int index = 7;
|
||||
unsigned int acc = number;
|
||||
if (acc == 0)
|
||||
string_buffer[index--] = '0';
|
||||
while (acc != 0) {
|
||||
string_buffer[index--] = dec_to_hex[acc%0x10];
|
||||
acc /= 0x10;
|
||||
}
|
||||
return (index+1);
|
||||
}
|
||||
|
||||
void printf(const char* string, ...) {
|
||||
va_list ptr;
|
||||
va_start(ptr, string);
|
||||
|
||||
int index = 0;
|
||||
int count = 0;
|
||||
char current;
|
||||
while (current=string[index++]) {
|
||||
count++;
|
||||
if (current == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y++;
|
||||
}
|
||||
|
||||
if (cursor_x == TERM_WIDTH) {
|
||||
cursor_x = 0;
|
||||
cursor_y++;
|
||||
}
|
||||
|
||||
if (cursor_y == TERM_HEIGHT) {
|
||||
for (int i=1; i<TERM_HEIGHT; i++) {
|
||||
for (int x=0; x<TERM_WIDTH; x++) {
|
||||
int from = i * TERM_WIDTH + x;
|
||||
int to = (i-1) * TERM_WIDTH + x;
|
||||
VMEM_ADDR[to] = VMEM_ADDR[from];
|
||||
}
|
||||
}
|
||||
clear_line(24);
|
||||
cursor_y--;
|
||||
}
|
||||
|
||||
if (current == '%') {
|
||||
int type = string[index++];
|
||||
int offset;
|
||||
switch (type) {
|
||||
case 'd':
|
||||
char decimal_buffer[11];
|
||||
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
|
||||
printf(decimal_buffer + offset);
|
||||
break;
|
||||
case 'x':
|
||||
char hex_buffer[8];
|
||||
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
|
||||
printf(hex_buffer + offset);
|
||||
break;
|
||||
case 's':
|
||||
printf(va_arg(ptr, const char*));
|
||||
break;
|
||||
case 'c':
|
||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
||||
int promoted = va_arg(ptr, int);
|
||||
char charred = promoted;
|
||||
VMEM_ADDR[mem_pos] = charred + (0x07<<8);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current != '\n') {
|
||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
||||
VMEM_ADDR[mem_pos] = current + (0x07<<8);
|
||||
}
|
||||
}
|
||||
|
||||
set_curpos(cursor_x, cursor_y);
|
||||
|
||||
va_end(ptr);
|
||||
}
|
||||
|
||||
void non_moving_put(char chr) {
|
||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x;
|
||||
VMEM_ADDR[mem_pos] = chr + (0x07<<8);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef SCREENSTUFF_H
|
||||
#define SCREENSTUFF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "types.h"
|
||||
#include "io.h"
|
||||
|
||||
uint16_t get_curpos();
|
||||
void init_term();
|
||||
void clear_screen();
|
||||
void clear_line(int line);
|
||||
void set_curpos_raw(int curpos);
|
||||
void set_curpos(int x, int y);
|
||||
int int_to_decimal(unsigned int number, char* string_buffer);
|
||||
int int_to_hex(unsigned int number, char* string_buffer);
|
||||
void printf(const char* string, ...);
|
||||
void non_moving_put(char chr);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "strings.h"
|
||||
|
||||
bool strcmp(char* a, char* b, int max) {
|
||||
int index = 0;
|
||||
while (index < max) {
|
||||
if (a[index] != b[index])
|
||||
return false;
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char* split_on_first(char delimeter, char* string) {
|
||||
int index = 0;
|
||||
char current;
|
||||
|
||||
while (current = string[index++]) {
|
||||
if (current == delimeter) {
|
||||
string[index-1] = 0;
|
||||
return string+index;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_split(char delimeter, char* string, char** pointer_array) {
|
||||
int index = 0;
|
||||
int last_split_index = 0;
|
||||
int split_count = 0;
|
||||
|
||||
char current;
|
||||
|
||||
while (current = string[index]) {
|
||||
if (current == delimeter) {
|
||||
string[index] = 0;
|
||||
pointer_array[split_count++] = (string+last_split_index);
|
||||
last_split_index = (index+1);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
// Add remaining part of the string to the pointer_array
|
||||
pointer_array[split_count] = (string+last_split_index);
|
||||
|
||||
return split_count;
|
||||
}
|
||||
|
||||
void decode_filename(char* nice_name, char* filenamebuffer) {
|
||||
// Clear filenamebuffer
|
||||
for (int i=0; i<11; i++)
|
||||
filenamebuffer[i] = ' ';
|
||||
filenamebuffer[11] = 0;
|
||||
|
||||
int fbIndex = 0;
|
||||
for (int i=0; i<12; i++) {
|
||||
if (nice_name[i] == 0)
|
||||
return;
|
||||
if (nice_name[i] == '.') {
|
||||
fbIndex = 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nice_name[i] >= 0x65 && nice_name[i] <= 0x65+26)
|
||||
filenamebuffer[fbIndex++] = nice_name[i] & (0xff - 32);
|
||||
else
|
||||
filenamebuffer[fbIndex++] = nice_name[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef STRINGS_H
|
||||
#define STRINGS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool strcmp(char* a, char* b, int max);
|
||||
char* split_on_first(char delimeter, char* string);
|
||||
int string_split(char delimeter, char* string, char** pointer_array);
|
||||
void decode_filename(char* nice_name, char* filenamebuffer);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user