the great porting of stuff over to GCC
This commit is contained in:
parent
7767782828
commit
d1083b4afe
14
src/bootloader/stage2/ctype.c
Normal file
14
src/bootloader/stage2/ctype.c
Normal file
@ -0,0 +1,14 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#include "ctype.h"
|
||||
|
||||
bool islower(char chr) {
|
||||
return chr >= 'a' && chr <= 'z';
|
||||
}
|
||||
|
||||
char toupper(char chr) {
|
||||
return islower(chr) ? (chr - 'a' + 'A') : chr;
|
||||
}
|
||||
11
src/bootloader/stage2/ctype.h
Normal file
11
src/bootloader/stage2/ctype.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool islower(char chr);
|
||||
char toupper(char chr);
|
||||
321
src/bootloader/stage2/fat.c
Normal file
321
src/bootloader/stage2/fat.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#include "fat.h"
|
||||
#include "stdio.h"
|
||||
#include "memdefs.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
#include "ctype.h"
|
||||
#include "minmax.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define MAX_PATH_SIZE 256
|
||||
#define MAX_FILE_HANDLES 10
|
||||
#define ROOT_DIRECTORY_HANDLE -1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t BootJumpInstruction[3];
|
||||
uint8_t OemIdentifier[8];
|
||||
uint16_t BytesPerSector;
|
||||
uint8_t SectorsPerCluster;
|
||||
uint16_t ReservedSectors;
|
||||
uint8_t FatCount;
|
||||
uint16_t DirEntryCount;
|
||||
uint16_t TotalSectors;
|
||||
uint8_t MediaDescriptorType;
|
||||
uint16_t SectorsPerFat;
|
||||
uint16_t SectorsPerTrack;
|
||||
uint16_t Heads;
|
||||
uint32_t HiddenSectors;
|
||||
uint32_t LargeSectorCount;
|
||||
|
||||
//Extended Boot Record
|
||||
uint8_t DriveNumber;
|
||||
uint8_t _Reserved;
|
||||
uint8_t Signature;
|
||||
uint32_t VolumeId; //Serial Can be whatever
|
||||
uint8_t VolumeLabel[11]; //11 Bytes MUST Be padded with spaces!
|
||||
uint8_t SystemId[8]; //8 Bytes padded with spaces (use MSWIN4.1 for best compatibility!)
|
||||
|
||||
} __attribute__((packed)) FAT_BootSector;
|
||||
|
||||
typedef struct {
|
||||
FAT_File Public;
|
||||
bool Opened;
|
||||
uint32_t FirstCluster;
|
||||
uint32_t CurrentCluster;
|
||||
uint32_t CurrentSectorInCluster;
|
||||
uint8_t Buffer[SECTOR_SIZE];
|
||||
|
||||
} __attribute__((packed)) FAT_FileData;
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
FAT_BootSector BootSector;
|
||||
uint8_t BootSectorBytes[SECTOR_SIZE];
|
||||
} BS;
|
||||
|
||||
FAT_FileData RootDirectory;
|
||||
|
||||
FAT_FileData OpenedFiles[MAX_FILE_HANDLES];
|
||||
|
||||
} FAT_Data;
|
||||
|
||||
static FAT_Data* g_Data;
|
||||
static uint8_t* g_Fat = NULL;
|
||||
static uint32_t g_DataSectionLba;
|
||||
|
||||
bool FAT_ReadBootSector(DISK* disk) {
|
||||
return DISK_ReadSectors(disk, 0, 1, &g_Data->BS.BootSectorBytes);
|
||||
}
|
||||
|
||||
bool FAT_ReadFat(DISK* disk)
|
||||
{
|
||||
return DISK_ReadSectors(disk, g_Data->BS.BootSector.ReservedSectors, g_Data->BS.BootSector.SectorsPerFat, g_Fat);
|
||||
}
|
||||
|
||||
bool FAT_Initialize(DISK* disk) {
|
||||
g_Data = (FAT_Data*)MEMORY_FAT_ADDR;
|
||||
|
||||
// read bootsector
|
||||
if (!FAT_ReadBootSector(disk)) {
|
||||
printf("FAT: Bootsector Read Failed!\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// read FAT
|
||||
g_Fat = (uint8_t*)(g_Data + sizeof(FAT_Data));
|
||||
uint32_t fatSize = g_Data->BS.BootSector.BytesPerSector * g_Data->BS.BootSector.SectorsPerFat;
|
||||
if(sizeof(FAT_Data) + fatSize >= MEMORY_FAT_SIZE) {
|
||||
printf("FAT: Not Enough Memory to Read FAT!\r\nNeeded %u, Only Have %u\r\n", sizeof(FAT_Data) + fatSize, MEMORY_FAT_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FAT_ReadFat(disk)) {
|
||||
printf("FAT: Failed to Read FAT!\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// open root dir
|
||||
uint32_t rootDirLba = g_Data->BS.BootSector.ReservedSectors + g_Data->BS.BootSector.SectorsPerFat * g_Data->BS.BootSector.FatCount;
|
||||
uint32_t rootDirSize = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
||||
|
||||
g_Data->RootDirectory.Public.Handle = ROOT_DIRECTORY_HANDLE;
|
||||
g_Data->RootDirectory.Public.IsDirectory = true;
|
||||
g_Data->RootDirectory.Public.Position = 0;
|
||||
g_Data->RootDirectory.Public.Size = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
||||
g_Data->RootDirectory.Opened = true;
|
||||
g_Data->RootDirectory.FirstCluster = rootDirLba;
|
||||
g_Data->RootDirectory.CurrentCluster = 0;
|
||||
g_Data->RootDirectory.CurrentSectorInCluster = 0;
|
||||
|
||||
if (!DISK_ReadSectors(disk, rootDirLba, 1, g_Data->RootDirectory.Buffer)) {
|
||||
printf("FAT: Failed to Read Root Directory!\r\n");
|
||||
return false;
|
||||
}
|
||||
//calculate data
|
||||
uint32_t rootDirSectors = (rootDirSize + g_Data->BS.BootSector.BytesPerSector - 1) / g_Data->BS.BootSector.BytesPerSector;
|
||||
g_DataSectionLba = rootDirLba + rootDirSectors;
|
||||
|
||||
// reset opened files
|
||||
for (int i = 0; i < MAX_FILE_HANDLES; i++)
|
||||
g_Data->OpenedFiles[i].Opened = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t FAT_ClusterToLba(uint32_t cluster) {
|
||||
return g_DataSectionLba + (cluster -2) * g_Data->BS.BootSector.SectorsPerCluster;
|
||||
}
|
||||
|
||||
FAT_File* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry) {
|
||||
// find empty handle
|
||||
int handle = -1;
|
||||
for (int i = 0; i < MAX_FILE_HANDLES && handle < 0; i++) {
|
||||
if (!g_Data->OpenedFiles[i].Opened)
|
||||
handle = i;
|
||||
}
|
||||
// out of handles
|
||||
if (handle < 0) {
|
||||
printf("FAT: Out of File Handles!\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup vars
|
||||
FAT_FileData* fd = &g_Data->OpenedFiles[handle];
|
||||
fd->Public.Handle = handle;
|
||||
fd->Public.IsDirectory = (entry->Attributes & FAT_ATTRIBUTE_DIRECTORY) != 0;
|
||||
fd->Public.Position = 0;
|
||||
fd->Public.Size = entry->Size;
|
||||
fd->FirstCluster = entry->FirstClusterLow + ((uint32_t)entry->FirstClusterHigh << 16);
|
||||
fd->CurrentCluster = fd->FirstCluster;
|
||||
fd->CurrentSectorInCluster = 0;
|
||||
|
||||
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster), 1, fd->Buffer)) {
|
||||
printf("FAT: Read Error!\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fd->Opened = true;
|
||||
return &fd->Public;
|
||||
}
|
||||
|
||||
uint32_t FAT_NextCluster(uint32_t currentCluster) {
|
||||
uint32_t fatIndex = currentCluster * 3 / 2;
|
||||
if (currentCluster % 2 == 0)
|
||||
return (*(uint16_t*)(g_Fat + fatIndex)) & 0x0FFF;
|
||||
else
|
||||
return (*(uint16_t*)(g_Fat + fatIndex)) >> 4;
|
||||
|
||||
}
|
||||
|
||||
uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut) {
|
||||
// get file data
|
||||
FAT_FileData* fd = (file->Handle == ROOT_DIRECTORY_HANDLE)
|
||||
? &g_Data->RootDirectory
|
||||
: &g_Data->OpenedFiles[file->Handle];
|
||||
|
||||
uint8_t* u8DataOut = (uint8_t*)dataOut;
|
||||
|
||||
// don't read past EOF
|
||||
if (!fd->Public.IsDirectory)
|
||||
byteCount = min(byteCount, fd->Public.Size - fd->Public.Position);
|
||||
|
||||
while (byteCount > 0) {
|
||||
uint32_t leftInBuffer = SECTOR_SIZE - (fd->Public.Position % SECTOR_SIZE);
|
||||
uint32_t take = min(byteCount, leftInBuffer);
|
||||
memcpy(u8DataOut, fd->Buffer + fd->Public.Position % SECTOR_SIZE, take);
|
||||
u8DataOut += take;
|
||||
fd->Public.Position += take;
|
||||
byteCount -= take;
|
||||
|
||||
// see if we need to read more data
|
||||
if (leftInBuffer == take) {
|
||||
// root dir handler
|
||||
if (fd->Public.Handle == ROOT_DIRECTORY_HANDLE) {
|
||||
++fd->CurrentCluster;
|
||||
// read next sect.
|
||||
if (!DISK_ReadSectors(disk, fd->CurrentCluster, 1, fd->Buffer)) {
|
||||
printf("FAT: Read Error!\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// read next sect.
|
||||
if (++fd->CurrentSectorInCluster >= g_Data->BS.BootSector.SectorsPerCluster) {
|
||||
// calc next cluster & sect. to read
|
||||
fd->CurrentSectorInCluster = 0;
|
||||
fd->CurrentCluster = FAT_NextCluster;
|
||||
}
|
||||
if (fd->CurrentCluster >= 0x0FF8) {
|
||||
// mark EOF
|
||||
fd->Public.Size = fd->Public.Position;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// read next sect.
|
||||
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster) + fd->CurrentSectorInCluster, 1, fd->Buffer)) {
|
||||
printf("FAT: Read Error!\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return u8DataOut - (uint8_t*)dataOut;
|
||||
}
|
||||
bool FAT_ReadEntry(DISK* disk, FAT_File* file, FAT_DirectoryEntry* dirEntry) {
|
||||
return FAT_Read(disk, file, sizeof(FAT_DirectoryEntry), dirEntry) == sizeof(FAT_DirectoryEntry);
|
||||
|
||||
}
|
||||
void FAT_Close(FAT_File* file) {
|
||||
if (file->Handle == ROOT_DIRECTORY_HANDLE) {
|
||||
file->Position = 0;
|
||||
g_Data->RootDirectory.CurrentCluster = g_Data->RootDirectory.FirstCluster;
|
||||
}
|
||||
else {
|
||||
g_Data->OpenedFiles[file->Handle].Opened = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FAT_FindFile(DISK* disk, FAT_File* file, const char* name, FAT_DirectoryEntry* entryOut) {
|
||||
char fatName[11];
|
||||
FAT_DirectoryEntry entry;
|
||||
|
||||
// convert from name to fat name
|
||||
memset(fatName, ' ', sizeof(fatName));
|
||||
const char* ext = strchr(name, '.');
|
||||
if (ext == NULL)
|
||||
ext = name + 11;
|
||||
for (int i = 0; i < 8 && name[i] && name + i < ext; i++)
|
||||
fatName[i] = toupper(name[i]);
|
||||
if (ext != NULL) {
|
||||
for (int i = 0; i < 3 && ext[i + 1]; i++)
|
||||
fatName[i + 8] = toupper(ext[i + 1]);
|
||||
}
|
||||
while (FAT_ReadEntry(disk, file, &entry)) {
|
||||
if (memcmp(fatName, entry.Name, 11) == 0) {
|
||||
*entryOut = entry;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FAT_File* FAT_Open(DISK* disk, const char* path) {
|
||||
char name[MAX_PATH_SIZE];
|
||||
|
||||
// ignore leading slash
|
||||
if (path[0] == '/')
|
||||
path++;
|
||||
|
||||
FAT_File* current = &g_Data->RootDirectory.Public;
|
||||
|
||||
while (*path) {
|
||||
// extract next file name from path
|
||||
bool isLast = false;
|
||||
const char* delim = strchr(path, '/');
|
||||
if (delim != NULL) {
|
||||
memcpy(name, path, delim - path);
|
||||
name[delim - path + 1] = '\0';
|
||||
path = delim + 1;
|
||||
}
|
||||
else {
|
||||
unsigned len = strlen(path);
|
||||
memcpy(name, path, len);
|
||||
name[len + 1] = '\0';
|
||||
path += len;
|
||||
bool isLast = true;
|
||||
}
|
||||
// find directory entry in current dir
|
||||
FAT_DirectoryEntry entry;
|
||||
if (FAT_FindFile(disk, current, name, &entry)) {
|
||||
FAT_Close(current);
|
||||
|
||||
// check if DIR
|
||||
if (!isLast && entry.Attributes & FAT_ATTRIBUTE_DIRECTORY == 0) {
|
||||
printf("FAT: %s is NOT a Directory!\r\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// open new DIR entry
|
||||
current = FAT_OpenEntry(disk, &entry);
|
||||
}
|
||||
else {
|
||||
FAT_Close(current);
|
||||
printf("FAT: %s NOT Found!", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
50
src/bootloader/stage2/fat.h
Normal file
50
src/bootloader/stage2/fat.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "disk.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Name[11];
|
||||
uint8_t Attributes;
|
||||
uint8_t _Reserved;
|
||||
uint8_t CreatedTimeTenths;
|
||||
uint16_t CreatedTime;
|
||||
uint16_t CreatedDate;
|
||||
uint16_t AccessedDate;
|
||||
uint16_t FirstClusterHigh;
|
||||
uint16_t ModifiedTime;
|
||||
uint16_t ModifiedDate;
|
||||
uint16_t FirstClusterLow;
|
||||
uint32_t Size;
|
||||
|
||||
} __attribute__((packed)) FAT_DirectoryEntry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int Handle;
|
||||
bool IsDirectory;
|
||||
uint32_t Position;
|
||||
uint32_t Size;
|
||||
} FAT_File;
|
||||
|
||||
enum FAT_Attributes {
|
||||
FAT_ATTRIBUTE_READ_ONLY = 0x01,
|
||||
FAT_ATTRIBUTE_HIDDEN = 0x02,
|
||||
FAT_ATTRIBUTE_SYSTEM = 0x04,
|
||||
FAT_ATTRIBUTE_VOLUME_ID = 0x08,
|
||||
FAT_ATTRIBUTE_DIRECTORY = 0x10,
|
||||
FAT_ATTRIBUTE_ARCHIVE = 0x20,
|
||||
FAT_ATTRIBUTE_LFN = FAT_ATTRIBUTE_READ_ONLY | FAT_ATTRIBUTE_HIDDEN | FAT_ATTRIBUTE_SYSTEM | FAT_ATTRIBUTE_VOLUME_ID
|
||||
};
|
||||
|
||||
|
||||
bool FAT_Initialize(DISK* disk);
|
||||
FAT_File* FAT_Open(DISK* disk, const char* path);
|
||||
uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut);
|
||||
bool FAT_ReadEntry(DISK* disk, FAT_File* file, FAT_DirectoryEntry* dirEntry);
|
||||
void FAT_Close(FAT_File* file);
|
||||
24
src/bootloader/stage2/memdefs.h
Normal file
24
src/bootloader/stage2/memdefs.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
// 0x00000000 - 0x000003FF - interrupt vector table
|
||||
// 0x00000400 - 0x000004FF - BIOS data area
|
||||
|
||||
#define MEMORY_MIN 0x00000500
|
||||
#define MEMORY_MAX 0x00080000
|
||||
|
||||
// 0x00000500 - 0x00010500 - FAT driver
|
||||
#define MEMORY_FAT_ADDR ((void*)0x20000)
|
||||
#define MEMORY_FAT_SIZE 0x00010000
|
||||
|
||||
// 0x00020000 - 0x00030000 - stage2
|
||||
|
||||
// 0x00030000 - 0x00080000 - free
|
||||
|
||||
// 0x00080000 - 0x0009FFFF - Extended BIOS data area
|
||||
// 0x000A0000 - 0x000C7FFF - Video
|
||||
// 0x000C8000 - 0x000FFFFF - BIOS
|
||||
36
src/bootloader/stage2/memory.c
Normal file
36
src/bootloader/stage2/memory.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#include "memory.h"
|
||||
|
||||
void* memcpy(void* dst, const void* src, uint16_t num) {
|
||||
uint8_t* u8Dst = (uint8_t *)dst;
|
||||
const uint8_t* u8Src = (const uint8_t *)src;
|
||||
|
||||
for (uint16_t i = 0; i < num; i++)
|
||||
u8Dst[i] = u8Src[i];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void* memset (void * ptr, int value, uint16_t num) {
|
||||
uint8_t* u8Ptr = (uint8_t *)ptr;
|
||||
|
||||
for (uint16_t i = 0; i < num; i++)
|
||||
u8Ptr[i] = (uint8_t)value;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int memcmp(const void* ptr1, const void * ptr2, uint16_t num) {
|
||||
const uint8_t* u8Ptr1 = (const uint8_t *)ptr1;
|
||||
const uint8_t* u8Ptr2 = (const uint8_t *)ptr2;
|
||||
|
||||
for (uint16_t i = 0; i < num; i++)
|
||||
if (u8Ptr1[i] != u8Ptr2[i])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
src/bootloader/stage2/memory.h
Normal file
11
src/bootloader/stage2/memory.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
void* memcpy(void* dst, const void* src, uint16_t num);
|
||||
void* memset(void* ptr, int value, uint16_t num);
|
||||
int memcmp(const void* ptr1, const void * ptr2, uint16_t num);
|
||||
9
src/bootloader/stage2/minmax.h
Normal file
9
src/bootloader/stage2/minmax.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
50
src/bootloader/stage2/string.c
Normal file
50
src/bootloader/stage2/string.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#include "string.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
const char* strchr(const char* str, char chr) {
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*str) {
|
||||
if (*str == chr)
|
||||
return str;
|
||||
|
||||
++str;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* strcpy(char* dst, const char* src) {
|
||||
char* origDst = dst;
|
||||
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src == NULL) {
|
||||
*dst = '\0';
|
||||
return dst;
|
||||
}
|
||||
while (*src) {
|
||||
*dst = *src;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
return origDst;
|
||||
}
|
||||
|
||||
unsigned strlen(const char* str) {
|
||||
unsigned len = 0;
|
||||
while (*str) {
|
||||
++len; ++str;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
10
src/bootloader/stage2/string.h
Normal file
10
src/bootloader/stage2/string.h
Normal file
@ -0,0 +1,10 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
const char* strchr(const char* str, char chr);
|
||||
char* strcpy(char* dst, const char* src);
|
||||
unsigned strlen(const char* str);
|
||||
@ -1,3 +1,8 @@
|
||||
;/////////////////////;
|
||||
;Nanite OS ;
|
||||
;COPYRIGHT (C) 2024 ;
|
||||
;Tyler McGurrin ;
|
||||
;/////////////////////;
|
||||
%macro x86_EnterRealMode 0
|
||||
[bits 32]
|
||||
jmp word 18h:.pmode16 ; 1 - jump to 16-bit protected mode segment
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
/*----------------*\
|
||||
|Nanite OS |
|
||||
|Copyright (C) 2024|
|
||||
|Tyler McGurrin |
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user