Blah blah blar add like FAT or something idfk
This commit is contained in:
parent
f1f3d95769
commit
ef7dbf8925
@ -367,7 +367,7 @@ disk_reset:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
msg_loading: db 'Loading Nanite...', ENDL, 0
|
msg_loading: db '', ENDL, 0
|
||||||
msg_read_failed: db 'Cant Read Disk!', ENDL, 0
|
msg_read_failed: db 'Cant Read Disk!', ENDL, 0
|
||||||
msg_no_stage2: db 'Cant Find Stage 2!', ENDL, 0
|
msg_no_stage2: db 'Cant Find Stage 2!', ENDL, 0
|
||||||
file_stage2_bin: db 'STAGE2 BIN'
|
file_stage2_bin: db 'STAGE2 BIN'
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
||||||
#define MAX_PATH_SIZE 256
|
#define MAX_PATH_SIZE 256
|
||||||
@ -126,6 +127,8 @@ bool FAT_Initialize(DISK* disk) {
|
|||||||
// reset opened files
|
// reset opened files
|
||||||
for (int i = 0; i < MAX_FILE_HANDLES; i++)
|
for (int i = 0; i < MAX_FILE_HANDLES; i++)
|
||||||
g_Data->OpenedFiles[i].Opened = false;
|
g_Data->OpenedFiles[i].Opened = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT_ClusterToLba(uint32_t cluster) {
|
uint32_t FAT_ClusterToLba(uint32_t cluster) {
|
||||||
@ -164,122 +167,155 @@ FAT_File far* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry) {
|
|||||||
return &fd->Public;
|
return &fd->Public;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT_File* FAT_Open(DISK* disk, const char* path) {
|
uint32_t FAT_NextCluster(uint32_t currentCluster) {
|
||||||
char buffer[MAX_PATH_SIZE];
|
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 far* file, uint32_t byteCount, void* dataOut) {
|
||||||
|
// get file data
|
||||||
|
FAT_FileData far* 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
|
||||||
|
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 (byteCount > 0) {
|
||||||
|
// 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) {
|
||||||
|
printf("FAT: Read Error, Invalid Next Cluster!\r\n");
|
||||||
|
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 far* file, FAT_DirectoryEntry* dirEntry) {
|
||||||
|
return FAT_Read(disk, file, sizeof(FAT_DirectoryEntry), dirEntry) == sizeof(FAT_DirectoryEntry);
|
||||||
|
|
||||||
|
}
|
||||||
|
void FAT_Close(FAT_File far* 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 far* 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 < 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 far* FAT_Open(DISK* disk, const char* path) {
|
||||||
|
char name[MAX_PATH_SIZE];
|
||||||
|
|
||||||
// ignore leading slash
|
// ignore leading slash
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
path++;
|
path++;
|
||||||
|
|
||||||
FAT_File far* parent = NULL;
|
FAT_File far* current = &g_Data->RootDirectory.Public;
|
||||||
FAT_File far* current = g_Data->RootDirectory.Public;
|
|
||||||
|
|
||||||
while (*path) {
|
while (*path) {
|
||||||
// extract next file name from path
|
// extract next file name from path
|
||||||
const char * delim = strchr(path, '/');
|
bool isLast = false;
|
||||||
|
const char* delim = strchr(path, '/');
|
||||||
if (delim != NULL) {
|
if (delim != NULL) {
|
||||||
memcpy(name, path, delim - path);
|
memcpy(name, path, delim - path);
|
||||||
name[delim - path + 1] = '\0';
|
name[delim - path + 1] = '\0';
|
||||||
path = delim + 1
|
path = delim + 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned len = strlen(path);
|
unsigned len = strlen(path);
|
||||||
memcpy(name, path, len);
|
memcpy(name, path, len);
|
||||||
name[len + 1] = '\0';
|
name[len + 1] = '\0';
|
||||||
path += len;
|
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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectoryEntry* findFile(const char* name)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < g_BootSector.DirEntryCount; i++)
|
|
||||||
{
|
|
||||||
if (memcmp(name, g_RootDirectory[i].Name, 11) == 0)
|
|
||||||
return &g_RootDirectory[i];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readFile(DirectoryEntry* fileEntry, FILE* disk, uint8_t* outputBuffer)
|
|
||||||
{
|
|
||||||
bool ok = true;
|
|
||||||
uint16_t currentCluster = fileEntry->FirstClusterLow;
|
|
||||||
|
|
||||||
do {
|
|
||||||
uint32_t lba = g_RootDirectoryEnd + (currentCluster - 2) * g_BootSector.SectorsPerCluster;
|
|
||||||
ok = ok && readSectors(disk, lba, g_BootSector.SectorsPerCluster, outputBuffer);
|
|
||||||
outputBuffer += g_BootSector.SectorsPerCluster * g_BootSector.BytesPerSector;
|
|
||||||
|
|
||||||
uint32_t fatIndex = currentCluster * 3 / 2;
|
|
||||||
if (currentCluster % 2 == 0)
|
|
||||||
currentCluster = (*(uint16_t*)(g_Fat + fatIndex)) & 0x0FFF;
|
|
||||||
else
|
|
||||||
currentCluster = (*(uint16_t*)(g_Fat + fatIndex)) >> 4;
|
|
||||||
|
|
||||||
} while (ok && currentCluster < 0x0FF8);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
if (argc < 3){
|
|
||||||
printf("Syntax: %s <disk image> <file name>\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* disk = fopen(argv[1], "rb");
|
|
||||||
if (!disk) {
|
|
||||||
fprintf(stderr, "Cannot open disk image %s!\n", argv[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readBootSector(disk)) {
|
|
||||||
fprintf(stderr, "Could not read boot sector!\n");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readFat(disk)) {
|
|
||||||
fprintf(stderr, "Could not read FAT!\n");
|
|
||||||
free(g_Fat);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readRootDirectory(disk)) {
|
|
||||||
fprintf(stderr, "Could not read root!\n");
|
|
||||||
free(g_Fat);
|
|
||||||
free(g_RootDirectory);
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectoryEntry* fileEntry = findFile(argv[2]);
|
|
||||||
if (!fileEntry) {
|
|
||||||
fprintf(stderr, "Could not locate file %s!\n", argv[2]);
|
|
||||||
free(g_Fat);
|
|
||||||
free(g_RootDirectory);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* buffer = (uint8_t*) malloc(fileEntry->Size + g_BootSector.BytesPerSector);
|
|
||||||
if (!readFile(fileEntry, disk, buffer)) {
|
|
||||||
fprintf(stderr, "Could not read file %s!\n", argv[2]);
|
|
||||||
free(g_Fat);
|
|
||||||
free(g_RootDirectory);
|
|
||||||
free(buffer);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < fileEntry->Size; i++)
|
|
||||||
{
|
|
||||||
if (isprint(buffer[i])) fputc(buffer[i], stdout);
|
|
||||||
//else printf("<%02x>", buffer[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
free(g_Fat);
|
|
||||||
free(g_RootDirectory);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,3 +1,8 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|Nanite OS |
|
||||||
|
|Copyright (C) 2024|
|
||||||
|
|Tyler McGurrin |
|
||||||
|
\*----------------*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
|
|||||||
@ -5,8 +5,41 @@
|
|||||||
\*----------------*/
|
\*----------------*/
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include "disk.h"
|
||||||
|
#include "fat.h"
|
||||||
|
|
||||||
|
#define VERSION "v0.0.1"
|
||||||
|
|
||||||
void _cdecl cstart_(uint16_t bootDrive) {
|
void _cdecl cstart_(uint16_t bootDrive) {
|
||||||
puts("Loading Main System\r\n");
|
|
||||||
|
printf("Loading NANITE %s\r\n\r\n", VERSION);
|
||||||
|
|
||||||
|
printf("Initializing FAT Driver...");
|
||||||
|
DISK disk;
|
||||||
|
if (!DISK_Initialize(&disk, bootDrive)) {
|
||||||
|
printf("Failed!\r\nDisk Init Error!");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Done!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// list files in root DIR
|
||||||
|
printf("Listing Files in Root Directory...");
|
||||||
|
FAT_File far* fd = FAT_Open(&disk, "/");
|
||||||
|
FAT_DirectoryEntry entry;
|
||||||
|
while (FAT_ReadEntry(&disk, fd, &entry)) {
|
||||||
|
printf(" ");
|
||||||
|
for (int i = 0; i < 11; i++)
|
||||||
|
putc(entry.Name[i]);
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
FAT_Close(fd);
|
||||||
printf("Done!\r\n");
|
printf("Done!\r\n");
|
||||||
|
|
||||||
|
|
||||||
|
end:
|
||||||
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -11,4 +11,26 @@ int memcpy(void far* dst, const void far* src, uint16_t num) {
|
|||||||
|
|
||||||
for (uint16_t i = 0; i < num; i++)
|
for (uint16_t i = 0; i < num; i++)
|
||||||
u8Dst[i] = u8Src[i];
|
u8Dst[i] = u8Src[i];
|
||||||
}
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void far* memset (void far * ptr, int value, uint16_t num) {
|
||||||
|
uint8_t far* u8Ptr = (uint8_t far *)ptr;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < num; i++)
|
||||||
|
u8Ptr[i] = (uint8_t)value;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void far* ptr1, const void far * ptr2, uint16_t num) {
|
||||||
|
const uint8_t far* u8Ptr1 = (const uint8_t far *)ptr1;
|
||||||
|
const uint8_t far* u8Ptr2 = (const uint8_t far *)ptr2;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < num; i++)
|
||||||
|
if (u8Ptr1[i] != u8Ptr2[i])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -6,4 +6,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
int memcpy(void far* dst, const void far* src, uint16_t num);
|
int memcpy(void far* dst, const void far* src, uint16_t num);
|
||||||
|
void far* memset(void far* ptr, int value, uint16_t num);
|
||||||
|
int memcmp(const void far* ptr1, const void far * ptr2, uint16_t num);
|
||||||
|
|||||||
@ -16,7 +16,9 @@ typedef unsigned long long int uint64_t;
|
|||||||
|
|
||||||
typedef uint8_t bool;
|
typedef uint8_t bool;
|
||||||
|
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
|||||||
@ -51,7 +51,7 @@ void _cdecl printf(const char* fmt, ...) {
|
|||||||
case PRINTF_STATE_NORMAL:
|
case PRINTF_STATE_NORMAL:
|
||||||
switch (*fmt)
|
switch (*fmt)
|
||||||
{
|
{
|
||||||
case '%': state = PRINTF_STATE_NORMAL;
|
case '%': state = PRINTF_STATE_LENGTH;
|
||||||
break;
|
break;
|
||||||
default: putc(*fmt);
|
default: putc(*fmt);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -46,4 +46,4 @@ unsigned strlen(const char* str) {
|
|||||||
++len; ++str;
|
++len; ++str;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,4 +7,4 @@
|
|||||||
|
|
||||||
const char* strchr(const char* str, char chr);
|
const char* strchr(const char* str, char chr);
|
||||||
char* strcpy(char* dst, const char* src);
|
char* strcpy(char* dst, const char* src);
|
||||||
unsigned strlen(const char* str);
|
unsigned strlen(const char* str);
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|Nanite OS |
|
||||||
|
|Copyright (C) 2024|
|
||||||
|
|Tyler McGurrin |
|
||||||
|
\*----------------*/
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
uint32_t align(uint32_t number, uint32_t alignTo) {
|
uint32_t align(uint32_t number, uint32_t alignTo) {
|
||||||
|
|||||||
@ -36,6 +36,31 @@ __U4D:
|
|||||||
shr edx, 16
|
shr edx, 16
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
;
|
||||||
|
; U4M
|
||||||
|
;
|
||||||
|
; Operation: Interger 4 Byte Multiplication
|
||||||
|
; Inputs: DX;AX INT M1
|
||||||
|
; CX;BX INT M2
|
||||||
|
; Outputs: DX;AX Product
|
||||||
|
; Volatile: CX;BX Destroyed
|
||||||
|
;
|
||||||
|
global __U4M
|
||||||
|
__U4M:
|
||||||
|
shl edx, 16 ;DX to upper 1/2 of EDX
|
||||||
|
mov dx, ax
|
||||||
|
mov eax, edx
|
||||||
|
|
||||||
|
shl ecx, 16
|
||||||
|
mov cx, bx
|
||||||
|
|
||||||
|
mul ecx
|
||||||
|
mov edx, eax
|
||||||
|
shr edx, 16
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
;void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotentOut, uint32_t* remainderOut);
|
;void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotentOut, uint32_t* remainderOut);
|
||||||
|
|||||||
4
write.sh
Normal file → Executable file
4
write.sh
Normal file → Executable file
@ -7,7 +7,7 @@ sudo make
|
|||||||
echo ---------
|
echo ---------
|
||||||
echo Finished!
|
echo Finished!
|
||||||
echo ---------
|
echo ---------
|
||||||
read -p "Do you want to write the IMG to Floppy? (/dev/sdb) (Y/n) " yn
|
read -p "Do you want to write the IMG to Floppy? (/dev/sdc) (y/n) " yn
|
||||||
|
|
||||||
case $yn in
|
case $yn in
|
||||||
y )
|
y )
|
||||||
@ -15,7 +15,7 @@ case $yn in
|
|||||||
echo Writing IMG to Floppy
|
echo Writing IMG to Floppy
|
||||||
echo ---------------------
|
echo ---------------------
|
||||||
|
|
||||||
sudo dd if=./build/main_floppy.img of=/dev/sdb
|
sudo dd if=./build/main_floppy.img of=/dev/sdc status=progress
|
||||||
|
|
||||||
echo ---------
|
echo ---------
|
||||||
echo Finished!
|
echo Finished!
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user