From c2f2728d244d2b5c427533356376281e28df33ef Mon Sep 17 00:00:00 2001 From: Tyler McGurrin Date: Mon, 2 Dec 2024 02:05:31 -0500 Subject: [PATCH] Done a bunch of stuff --- Makefile | 6 +- build.sh | 0 build/stage1.bin | Bin 512 -> 0 bytes build/stage2/asm/main.obj | Bin 151 -> 0 bytes build/stage2/asm/x86.obj | Bin 240 -> 0 bytes build/stage2/c/main.obj | Bin 1887 -> 0 bytes src/bootloader/stage1/boot.asm | 2 +- src/bootloader/stage2/Makefile | 6 +- src/bootloader/stage2/disk.c | 43 +++++++ src/bootloader/stage2/disk.h | 4 +- src/bootloader/stage2/fat.c | 201 ++++++++++++++++++++++++++++++++ src/bootloader/stage2/fat.h | 47 ++++++++ src/bootloader/stage2/main.c | 7 +- src/bootloader/stage2/main.err | 1 - src/bootloader/stage2/memdefs.h | 19 +++ src/bootloader/stage2/stdint.h | 2 + src/bootloader/stage2/stdio.err | 5 - src/bootloader/stage2/string.c | 36 ++++++ src/bootloader/stage2/string.h | 4 + src/bootloader/stage2/utility.c | 9 ++ src/bootloader/stage2/utility.h | 4 + src/bootloader/stage2/x86.asm | 139 +++++++++++++++++++++- src/bootloader/stage2/x86.h | 10 +- test.txt | 1 + 24 files changed, 517 insertions(+), 29 deletions(-) mode change 100644 => 100755 build.sh delete mode 100644 build/stage1.bin delete mode 100644 build/stage2/asm/main.obj delete mode 100644 build/stage2/asm/x86.obj delete mode 100644 build/stage2/c/main.obj create mode 100644 src/bootloader/stage2/disk.c create mode 100644 src/bootloader/stage2/fat.c create mode 100644 src/bootloader/stage2/fat.h delete mode 100644 src/bootloader/stage2/main.err create mode 100644 src/bootloader/stage2/memdefs.h delete mode 100644 src/bootloader/stage2/stdio.err create mode 100644 src/bootloader/stage2/string.c create mode 100644 src/bootloader/stage2/string.h create mode 100644 src/bootloader/stage2/utility.c create mode 100644 src/bootloader/stage2/utility.h create mode 100644 test.txt diff --git a/Makefile b/Makefile index 3294603..580d2b1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ ASM=nasm CC=gcc -CC16=/usr/bin/watcom/binl/wcc -LD16=/usr/bin/watcom/binl/wlink +CC16=/opt/watcom/binl/wcc +LD16=/opt/watcom/binl/wlink SRC_DIR=src TOOLS_DIR=tools @@ -22,7 +22,7 @@ $(BUILD_DIR)/main_floppy.img: bootloader kernel dd if=$(BUILD_DIR)/stage1.bin of=$(BUILD_DIR)/main_floppy.img conv=notrunc mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/stage2.bin "::stage2.bin" mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/kernel.bin "::kernel.bin" - mcopy -i $(BUILD_DIR)/main_floppy.img readme.txt "::readme.txt" + mcopy -i $(BUILD_DIR)/main_floppy.img test.txt "::test.txt" # # Bootloader diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/build/stage1.bin b/build/stage1.bin deleted file mode 100644 index d57c15d29e119b50c053fd040396586b74c24856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmaEDJHaodvuJ*+T2DU96XNCEj&M>eyJhV4>+sP+U^Y2)P znN-a}v6?P9ff|GV-ybux@zn$@6s$S;fYtEQcQfvq)=MRf4jl(0x`4*)W~h5{hr#gn zeulbzA8U7VGlYL$7GJ{Cd|biVT28R0=GE)UZda+re`*)K0nG(!d$EFHH-kdo z;oS@j3;)zMACTY32o|2mz%0jI0~FfH%<%o;P9}!$ANMiTF&?w)X5qY4!g}xp%WG!U z|NOQ;_={PAhQ2-o(zOF<63~CIfI*?~TIko8eWz+)h%&t9*mtM)1uw&EhAj+d#ekCk z|Nr_D77)CK<3I_=7QXEaX9Zq=j*f^s91sNZmPCzH=S2`hs;1*w$I$~%*f<_WbR3E} z91t8B6dw5E#{Y;dO#7J`5`LZ)F6K^r!N=g=`oHw!>q&|6QIXLRhZD9i0A-4r6AuTM zBo>uq=A|q6CFW(8q$(Kb8R!`%>gnn6axpk3=9MS}r6#5*xMUV*E5bzFGV@Xtfcnx? X6^uZF!6As?F?3?%?pwom~8 diff --git a/build/stage2/c/main.obj b/build/stage2/c/main.obj deleted file mode 100644 index cea7dd36618219a8d76eed5b7474fb59bc78a24c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1887 zcmbtU-EZ4e6hGIFW5-UKq$x$Cg1Kyb3MDjcqY5TQnrv;Qb(vZ>r2}Rqj++`KcCno@ zF@#E6qzrf%48njsEFgq{KY+a;ga~3n;tePWX+olts5J44gv83ZZbJ)?ouzy2bAIRi z&c{91%SYgm#DZ1T6K4%uv&=-+(rQ)Rbe+V>f@!#V!m+hP(X!l%RVe9p!f^{_J(;K$ z3^T6f>ntp{l)3=R?+rRRz4Uf{6qYxC^9|440_!vNERtj|CFhRpCpE_{8KxUwc(I;A zn#^0txkvX)W5pN#q$O?!8~p&jOfGxOmrW~ac6550RZdL%vtv`anNysq9D73f^b!yE z9|WEukva#D4??yPsp(&wE>vQ0~ zz<|^keJYk&#zJ@5JO%ILR2&C4H3Xcni*k^_Olia0TFZfGaYb!q;k>Ie+76^~_h@%^0-B9>T1J@=QBI zKYH@)M{mXeNC0C<5P%@y6v6@c>+&ESficT4%ksQ!RpqlIDLFkoDZ7@Oku|HN_lHE7 zz+ahBs2I=dB`VIeu&GO47k0YiATPIM871Ihjr@oZS;Z~DiU6Hz2oO{;uloTG;`>5> zo3_)<+QyQOYJq*@Ze|WGia$_KOb(wro43K$LwV9pDWpAu>ol&X6!LOQ1TKgM>u6hP z;q|8U1gRasp{n3)azw1oxUq#YR`c(d` z$$8E)hQ~4h?!YyCA&lkjo*E`kv!n3$=zosdVjF1Da4!lxMX2LY>p2jpP{qYS1a|^k zJ`wvwJLNq`*;~AoEWO$+mgVONE0BT1LrDKgGXU)~*Z@r-rPd2T(*q_-NQ@OC{#dwA zxJMWbXZ*vFm9(^)#!|V%zzUB^l7yq*3rUF;CUBnCNF05V(nRc`@Ntn9js|5ZCEXW1 yAq@o|6r-e@3`&n9d7E(P&WLMik-8Nn^r9$69mB&zQhX+{HzDr}xA9jnZ}%V4nb8mc diff --git a/src/bootloader/stage1/boot.asm b/src/bootloader/stage1/boot.asm index b8e7726..df87676 100644 --- a/src/bootloader/stage1/boot.asm +++ b/src/bootloader/stage1/boot.asm @@ -367,7 +367,7 @@ disk_reset: ret -msg_loading: db 'Starting Nanite 0.0.1a...', ENDL, 0 +msg_loading: db 'Loading Nanite...', ENDL, 0 msg_read_failed: db 'Cant Read Disk!', ENDL, 0 msg_no_stage2: db 'Cant Find Stage 2!', ENDL, 0 file_stage2_bin: db 'STAGE2 BIN' diff --git a/src/bootloader/stage2/Makefile b/src/bootloader/stage2/Makefile index 191024a..fffd50e 100644 --- a/src/bootloader/stage2/Makefile +++ b/src/bootloader/stage2/Makefile @@ -1,9 +1,9 @@ BUILD_DIR?=build/ ASM?=nasm ASMFLAGS?=-f obj -CC16?=/usr/bin/watcom/binl/wcc -CFLAGS16?=-4 -d3 -s -wx -ms -zl -zq # -oneatxzh -LD16?=/usr/bin/watcom/binl/wlink +CC16?=/opt/watcom/binl/wcc +CFLAGS16?=-4 -d3 -s -wx -ms -zl -zq -za99 # -oneatxzh +LD16?=/opt/watcom/binl/wlink SOURCES_C=$(wildcard *.c) SOURCES_ASM=$(wildcard *.asm) diff --git a/src/bootloader/stage2/disk.c b/src/bootloader/stage2/disk.c new file mode 100644 index 0000000..a795783 --- /dev/null +++ b/src/bootloader/stage2/disk.c @@ -0,0 +1,43 @@ +#include "disk.h" +#include "x86.h" +#include "stdio.h" + +bool DISK_Initialize(DISK* disk, uint8_t driveNumber) { + uint8_t driveType; + uint16_t cylinders, sectors, heads; + + if (!x86_Disk_GetDriveParams(disk->id, &driveType, &cylinders, §ors, &heads)) + return false; + + disk->id = driveNumber; + disk->cylinders = cylinders; + disk->heads = heads; + disk->sectors = sectors; + + return true; +} + +void DISK_LBA2CHS(DISK* disk, uint32_t lba, uint16_t* cylinderOut, uint16_t* sectorOut, uint16_t* headOut) { + // sector = (LBA % sectors per track + 1) + *sectorOut = lba % disk->sectors +1; + + // cylinder = (LBA / sects per track / heads) + *cylinderOut = (lba / disk->sectors) / disk->heads; + + // head = (LBA / sects per track % heads) + *headOut = (lba / disk->sectors) % disk->heads; +} + +bool DISK_ReadSectors(DISK* disk, uint32_t lba, uint8_t sectors, void far* dataOut) { + uint16_t cylinder, sector, head; + + DISK_LBA2CHS(disk, lba, &cylinder, §or, &head); + + for (int i = 0; i < 3; i++) { + if (x86_Disk_Read(disk->id, cylinder, sector, head, sectors, dataOut)) + return true; + x86_Disk_Reset(disk->id); + } + + return false; +} diff --git a/src/bootloader/stage2/disk.h b/src/bootloader/stage2/disk.h index 62faffe..8b20239 100644 --- a/src/bootloader/stage2/disk.h +++ b/src/bootloader/stage2/disk.h @@ -12,8 +12,8 @@ typedef struct { uint16_t cylinders; uint16_t sectors; uint16_t heads; -}; +} DISK; bool DISK_Initialize(DISK* disk, uint8_t driveNumber); -bool DISK_ReadSectors(DISK* disk, uint32_t lba, uint8_t far* dataOut); +bool DISK_ReadSectors(DISK* disk, uint32_t lba, uint8_t sectors, void far* dataOut); diff --git a/src/bootloader/stage2/fat.c b/src/bootloader/stage2/fat.c new file mode 100644 index 0000000..f7cba59 --- /dev/null +++ b/src/bootloader/stage2/fat.c @@ -0,0 +1,201 @@ +#include "fat.h" +#include "stdio.h" +#include "memdefs.h" +#include "utility.h" + +#define SECTOR_SIZE 512 + +#pragma pack(push,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!) + +} FAT_BootSector; +#pragma pack(pop) + +typedef struct { + union { + FAT_BootSector Bootsector; + uint8_t BootsectorBytes[SECTOR_SIZE]; + } BS; + +} FAT_Data; + +static FAT_Data far* g_Data; +static uint8_t far* g_Fat = NULL; +static FAT_DirectoryEntry far* g_RootDirectory = NULL; +static uint32_t g_RootDirectoryEnd; + +bool FAT_ReadBootSector(FILE* disk) { + return DISK_ReadSectors(disk, 0, 1, &g_Data->BS.BootSectorBytes); +} + +bool FAT_ReadFat(DISK* disk) +{ + return DISK_ReadSectors(disk, g_Data->g_BootSector.ReservedSectors, g_Data->g_BootSector.SectorsPerFat, g_Fat); +} + +bool FAT_ReadRootDirectory(DISK* disk) +{ + uint32_t lba = g_Data->g_BootSector.ReservedSectors + g_Data->g_BootSector.SectorsPerFat * g_Data->g_BootSector.FatCount; + uint32_t size = sizeof(FAT_DirectoryEntry) * g_Data->g_BootSector.DirEntryCount; + uint32_t sectors = (size + g_Data->g_BootSector.BytesPerSector - 1) / g_Data->g_BootSector.BytesPerSector; + + g_RootDirectoryEnd = lba + sectors; + return DISK_ReadSectors(disk, lba, sectors, g_RootDirectory); +} + +bool FAT_Initialize(DISK* disk) { + g_Data = (FAT_Data far*)MEMORY_FAT_ADDR; + + // read bootsector + if (!FAT_ReadBootSector(disk)) { + printf("FAT: Bootsector Read Failed!\r\n"); + return false; + } + + // read FAT + g_Fat = (uint8_t far*)(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; + } + // read root dir (/) + g_RootDirectory = (FAT_DirectoryEntry far*)(g_Fat + fatSize); + uint32_t rootDirSize = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount; + rootDirSize = align(rootDirSize, g_Data->BS.BootSector.BytesPerSector); + + if (sizeof(FAT_Data) + fatSize + rootDirSize >= MEMORY_FAT_SIZE) { + printf("FAT: Not Enough Memory to Read Root Directory!\r\nNeeded %u, Only Have %u\r\n", sizeof(FAT_Data) + fatSize + rootDirSize, MEMORY_FAT_SIZE); + return false; + } + + if(!FAT_ReadRootDirectory(disk)) { + printf("FAT: Failed to Read Root Directory!\r\n"); + return false; + } +} + +FAT_File far* FAT_Open(DISK* disk, const char* path) { + +} + +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; +} + +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 \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; +} diff --git a/src/bootloader/stage2/fat.h b/src/bootloader/stage2/fat.h new file mode 100644 index 0000000..2c75eae --- /dev/null +++ b/src/bootloader/stage2/fat.h @@ -0,0 +1,47 @@ +#pragma once +#include "stdint.h" +#include "disk.h" + +#pragma pack(push, 1) +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; + +} FAT_DirectoryEntry; +#pragma pack(pop) + +typdef 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 far* FAT_Open(DISK* disk, const char* path); +uint32_t FAT_Read(DISK* disk, FAT_File far* file, uint32_t byteCount, void* dataOut); +bool FAT_ReadEntry(DISK* disk, FAT_File far* file, FAT_DirectoryEntry* dirEntry); +void FAT_Close(FAT_File far* file); diff --git a/src/bootloader/stage2/main.c b/src/bootloader/stage2/main.c index f420738..916e41e 100644 --- a/src/bootloader/stage2/main.c +++ b/src/bootloader/stage2/main.c @@ -6,8 +6,7 @@ #include "stdint.h" #include "stdio.h" -void _cdecl cstart_(uint16_t bootDrive) -{ - puts("Going from x86 ASM to C code!\r\n"); - printf("Initialized!\r\n"); +void _cdecl cstart_(uint16_t bootDrive) { + puts("Loading Main System\r\n"); + printf("Done!\r\n"); } diff --git a/src/bootloader/stage2/main.err b/src/bootloader/stage2/main.err deleted file mode 100644 index e39ad6c..0000000 --- a/src/bootloader/stage2/main.err +++ /dev/null @@ -1 +0,0 @@ -main.c(9): Warning! W303: Parameter 'bootDrive' has been defined, but not referenced diff --git a/src/bootloader/stage2/memdefs.h b/src/bootloader/stage2/memdefs.h new file mode 100644 index 0000000..c3fe589 --- /dev/null +++ b/src/bootloader/stage2/memdefs.h @@ -0,0 +1,19 @@ +#pragma once + +// 0x00000000 - 0x000003FF - int vector table +// 0x00000400 - 0x000004FF - Bios Data + +#define MEMORY_MIN 0x00000500 +#define MEMORY_MAX 0x00080000 + +// 0x00000500 - 0x00010500 - FAT Driver +#define MEMORY_FAT_ADDR ((void far*)0x00500000) // segment:offset SSSS:OOOO +#define MEMORY_FAT_SIZE 0x00010500 + +// 0x00020000 - 0x00030000 - stage2 + +// 0x00030000 - 0x00080000 - free + +// 0x00080000 - 0x0009FFFF - Extended BIOS data area +// 0x000A0000 - 0x000C7FFF - Video +// 0x000C8000 - 0x000FFFFF - BIOS diff --git a/src/bootloader/stage2/stdint.h b/src/bootloader/stage2/stdint.h index 5b4266b..ca0d7f9 100644 --- a/src/bootloader/stage2/stdint.h +++ b/src/bootloader/stage2/stdint.h @@ -18,3 +18,5 @@ typedef uint8_t bool; #define true 1 #define false 0 + +#define NULL ((void*)0) \ No newline at end of file diff --git a/src/bootloader/stage2/stdio.err b/src/bootloader/stage2/stdio.err deleted file mode 100644 index b1e31d6..0000000 --- a/src/bootloader/stage2/stdio.err +++ /dev/null @@ -1,5 +0,0 @@ -x86.h(22): Error! E1009: Expecting ',' or ';' but found 'x86_Disk_GetDriveParams' -stdio.c(100): Warning! W100: Parameter 1 contains inconsistent levels of indirection -stdio.c(100): Note! I2003: source conversion type is 'char **' -stdio.c(100): Note! I2004: target conversion type is 'char const *' -stdio.c(100): Note! I2002: 'puts' defined in: stdio.c(14) diff --git a/src/bootloader/stage2/string.c b/src/bootloader/stage2/string.c new file mode 100644 index 0000000..adcacfd --- /dev/null +++ b/src/bootloader/stage2/string.c @@ -0,0 +1,36 @@ +#include "string.h" +#include "stdint.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; +} \ No newline at end of file diff --git a/src/bootloader/stage2/string.h b/src/bootloader/stage2/string.h new file mode 100644 index 0000000..d7318b8 --- /dev/null +++ b/src/bootloader/stage2/string.h @@ -0,0 +1,4 @@ +#pragma once + +const char* strchr(const char* str, char chr); +char* strcpy(char* dst, const char* src); \ No newline at end of file diff --git a/src/bootloader/stage2/utility.c b/src/bootloader/stage2/utility.c new file mode 100644 index 0000000..d170209 --- /dev/null +++ b/src/bootloader/stage2/utility.c @@ -0,0 +1,9 @@ +#include "utility.h" + +uint32_t align(uint32_t number, uint32_t alignTo) { + if (alignTo == 0) + return number; + + uint32_t rem = number % alignTo; + return (rem > 0) ? (number + alignTo - rem) : number; +} diff --git a/src/bootloader/stage2/utility.h b/src/bootloader/stage2/utility.h new file mode 100644 index 0000000..dc170b8 --- /dev/null +++ b/src/bootloader/stage2/utility.h @@ -0,0 +1,4 @@ +#pragma once +#include "stdint.h" + +uint32_t align(uint32_t number, uint32_t alignTo); diff --git a/src/bootloader/stage2/x86.asm b/src/bootloader/stage2/x86.asm index ec02a55..91b0988 100644 --- a/src/bootloader/stage2/x86.asm +++ b/src/bootloader/stage2/x86.asm @@ -7,12 +7,42 @@ bits 16 section _TEXT class=CODE +; +; U4D +; +; Operation: Unsigned 4 byte divide +; Inputs: DX;AX Dividend +; CX;BX Divisor +; Outputs: DX;AX Quotient +; CX;BX Remainder +; Volatile: none +; +global __U4D +__U4D: + shl edx, 16 ; dx to upper half of edx + mov dx, ax ; edx - dividend + mov eax, edx ; eax - dividend + xor edx, edx + + shl ecx, 16 ; cx to upper half of ecx + mov cx, bx ; ecx - divisor + + div ecx ; eax - quot, edx - remainder + mov ebx, edx + mov ecx, edx + shr ecx, 16 + + mov edx, eax + shr edx, 16 + + ret + ; ;void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotentOut, uint32_t* remainderOut); ; global _x86_div64_32 -_x86_div64_32 +_x86_div64_32: ;make new call frame push bp ;save old call frame mov bp, sp ;init new call frame @@ -71,7 +101,7 @@ _x86_Video_WriteCharTeletype: ; -;void _cdecl x86_Disk_Reset(uint8_t drive); +; bool _cdecl x86_Disk_Reset(uint8_t drive); ; global _x86_Disk_Reset _x86_Disk_Reset: @@ -79,7 +109,13 @@ _x86_Disk_Reset: push bp ;save old call frame mov bp, sp ;init new call frame - + mov ah, 0 + mov dl, [bp + 4]; dl - drive + std + int 13h + + mov ax, 1 + sbb ax, 0 ; 1 is true 0 is false ;restore old call frame mov sp, bp @@ -88,15 +124,108 @@ _x86_Disk_Reset: ; -;void _cdecl x86_Disk_Read(uint8_t drive, +; bool _cdecl x86_Disk_Read(uint8_t drive, ; uint16_t cylinder, ; uint16_t head, ; uint16_t sector, ; uint8_t count, ; uint8_t far * dataout); ; -;void _cdelc x86_Disk_GetDriveParams(uint8_t drive, +global _x86_Disk_Read +_x86_Disk_Read: + ;make new call frame + push bp ;save old call frame + mov bp, sp ;init new call frame + + ;setup args + mov dl, [bp + 4]; dl - drive + + mov ch, [bp + 6]; ch - cylinder (lower 8 bits) + mov cl, [bp + 7]; cl - cylinder to to bits 6-7 + shl cl, 6 + + mov dh, [bp + 10]; dh - head + + mov al, [bp + 8]; cl - sectory to bits 0-5 + and al, 3Fh + or cl, al + + mov al, [bp + 12]; count + + mov bx, [bp + 16]; es:bx - far pointer to data out + mov es, bx + mov bx, [bp + 14] + + ; call + mov al, 02h + std + int 13h + + mov ax, 1 + sbb ax, 0 ; 1 is true 0 is false + + ; restore old call frame + mov sp, bp + pop bp + ret + + + +; bool _cdelc x86_Disk_GetDriveParams(uint8_t drive, ; uint8_t* driveTypeOut, ; uint16_t* cylindersOut, ; uint16_t* sectorsOut, ; uint16_t* headsOut); +global _x86_Disk_GetDriveParams +_x86_Disk_GetDriveParams: + ; make new call frame + push bp ; save old frame + mov bp, sp ; init new frame + + ; save regs + push es + push bx + push si + push di + + ; call int13h + mov dl, [bp + 4] ;dl - drive + mov ah, 08h + mov di, 0 ;es:di - 0000:0000 + mov es, di + stc + int 13h + + ; return + mov ax, 1 + sbb ax, 0 + + ; out params + mov si, [bp + 6] ; drive type + mov [si], bl + + mov bl, ch ; cyl - lower bits in ch + mov bh, cl ; cyl - upper bits in ch (6-7) + shr bh, 6 + mov si, [bp + 8] + mov [si], bx + + xor ch, ch ; sectors - lower 5 bits of cl + and cl, 3Fh + mov si, [bp + 10] + mov [si], cx + + mov cl, dh + mov si, [bp + 12] + mov [si], cx + + ; restore regs + pop di + pop si + pop bx + pop es + + ; restore old call frame + mov sp, bp + pop bp + ret \ No newline at end of file diff --git a/src/bootloader/stage2/x86.h b/src/bootloader/stage2/x86.h index db1366c..1bc1435 100644 --- a/src/bootloader/stage2/x86.h +++ b/src/bootloader/stage2/x86.h @@ -10,16 +10,16 @@ void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotentO void _cdecl x86_Video_WriteCharTeletype(char c, uint8_t page); -void _cdecl x86_Disk_Reset(uint8_t drive); +bool _cdecl x86_Disk_Reset(uint8_t drive); -void _cdecl x86_Disk_Read(uint8_t drive, +bool _cdecl x86_Disk_Read(uint8_t drive, uint16_t cylinder, - uint16_t head, uint16_t sector, + uint16_t head, uint8_t count, - uint8_t far * dataout); + void far * dataout); -void _cdelc x86_Disk_GetDriveParams(uint8_t drive, +bool _cdecl x86_Disk_GetDriveParams(uint8_t drive, uint8_t* driveTypeOut, uint16_t* cylindersOut, uint16_t* sectorsOut, diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..22488fb --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +this is text test har har har har *insert meme here* har har har \ No newline at end of file