Done a bunch of stuff
This commit is contained in:
parent
f9679793ef
commit
c2f2728d24
6
Makefile
6
Makefile
@ -1,7 +1,7 @@
|
|||||||
ASM=nasm
|
ASM=nasm
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CC16=/usr/bin/watcom/binl/wcc
|
CC16=/opt/watcom/binl/wcc
|
||||||
LD16=/usr/bin/watcom/binl/wlink
|
LD16=/opt/watcom/binl/wlink
|
||||||
|
|
||||||
SRC_DIR=src
|
SRC_DIR=src
|
||||||
TOOLS_DIR=tools
|
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
|
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)/stage2.bin "::stage2.bin"
|
||||||
mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/kernel.bin "::kernel.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
|
# Bootloader
|
||||||
|
|||||||
BIN
build/stage1.bin
BIN
build/stage1.bin
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -367,7 +367,7 @@ disk_reset:
|
|||||||
ret
|
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_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'
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
BUILD_DIR?=build/
|
BUILD_DIR?=build/
|
||||||
ASM?=nasm
|
ASM?=nasm
|
||||||
ASMFLAGS?=-f obj
|
ASMFLAGS?=-f obj
|
||||||
CC16?=/usr/bin/watcom/binl/wcc
|
CC16?=/opt/watcom/binl/wcc
|
||||||
CFLAGS16?=-4 -d3 -s -wx -ms -zl -zq # -oneatxzh
|
CFLAGS16?=-4 -d3 -s -wx -ms -zl -zq -za99 # -oneatxzh
|
||||||
LD16?=/usr/bin/watcom/binl/wlink
|
LD16?=/opt/watcom/binl/wlink
|
||||||
|
|
||||||
SOURCES_C=$(wildcard *.c)
|
SOURCES_C=$(wildcard *.c)
|
||||||
SOURCES_ASM=$(wildcard *.asm)
|
SOURCES_ASM=$(wildcard *.asm)
|
||||||
|
|||||||
43
src/bootloader/stage2/disk.c
Normal file
43
src/bootloader/stage2/disk.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
@ -12,8 +12,8 @@ typedef struct {
|
|||||||
uint16_t cylinders;
|
uint16_t cylinders;
|
||||||
uint16_t sectors;
|
uint16_t sectors;
|
||||||
uint16_t heads;
|
uint16_t heads;
|
||||||
};
|
} DISK;
|
||||||
|
|
||||||
bool DISK_Initialize(DISK* disk, uint8_t driveNumber);
|
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);
|
||||||
|
|
||||||
|
|||||||
201
src/bootloader/stage2/fat.c
Normal file
201
src/bootloader/stage2/fat.c
Normal file
@ -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 <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;
|
||||||
|
}
|
||||||
47
src/bootloader/stage2/fat.h
Normal file
47
src/bootloader/stage2/fat.h
Normal file
@ -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);
|
||||||
@ -6,8 +6,7 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
|
||||||
void _cdecl cstart_(uint16_t bootDrive)
|
void _cdecl cstart_(uint16_t bootDrive) {
|
||||||
{
|
puts("Loading Main System\r\n");
|
||||||
puts("Going from x86 ASM to C code!\r\n");
|
printf("Done!\r\n");
|
||||||
printf("Initialized!\r\n");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
main.c(9): Warning! W303: Parameter 'bootDrive' has been defined, but not referenced
|
|
||||||
19
src/bootloader/stage2/memdefs.h
Normal file
19
src/bootloader/stage2/memdefs.h
Normal file
@ -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
|
||||||
@ -18,3 +18,5 @@ typedef uint8_t bool;
|
|||||||
|
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
|
#define NULL ((void*)0)
|
||||||
@ -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)
|
|
||||||
36
src/bootloader/stage2/string.c
Normal file
36
src/bootloader/stage2/string.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
4
src/bootloader/stage2/string.h
Normal file
4
src/bootloader/stage2/string.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
const char* strchr(const char* str, char chr);
|
||||||
|
char* strcpy(char* dst, const char* src);
|
||||||
9
src/bootloader/stage2/utility.c
Normal file
9
src/bootloader/stage2/utility.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
4
src/bootloader/stage2/utility.h
Normal file
4
src/bootloader/stage2/utility.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
uint32_t align(uint32_t number, uint32_t alignTo);
|
||||||
@ -7,12 +7,42 @@ bits 16
|
|||||||
|
|
||||||
section _TEXT class=CODE
|
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);
|
;void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotentOut, uint32_t* remainderOut);
|
||||||
;
|
;
|
||||||
|
|
||||||
global _x86_div64_32
|
global _x86_div64_32
|
||||||
_x86_div64_32
|
_x86_div64_32:
|
||||||
;make new call frame
|
;make new call frame
|
||||||
push bp ;save old call frame
|
push bp ;save old call frame
|
||||||
mov bp, sp ;init new 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
|
global _x86_Disk_Reset
|
||||||
_x86_Disk_Reset:
|
_x86_Disk_Reset:
|
||||||
@ -79,7 +109,13 @@ _x86_Disk_Reset:
|
|||||||
push bp ;save old call frame
|
push bp ;save old call frame
|
||||||
mov bp, sp ;init new 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
|
;restore old call frame
|
||||||
mov sp, bp
|
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 cylinder,
|
||||||
; uint16_t head,
|
; uint16_t head,
|
||||||
; uint16_t sector,
|
; uint16_t sector,
|
||||||
; uint8_t count,
|
; uint8_t count,
|
||||||
; uint8_t far * dataout);
|
; 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,
|
; uint8_t* driveTypeOut,
|
||||||
; uint16_t* cylindersOut,
|
; uint16_t* cylindersOut,
|
||||||
; uint16_t* sectorsOut,
|
; uint16_t* sectorsOut,
|
||||||
; uint16_t* headsOut);
|
; 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
|
||||||
@ -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_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 cylinder,
|
||||||
uint16_t head,
|
|
||||||
uint16_t sector,
|
uint16_t sector,
|
||||||
|
uint16_t head,
|
||||||
uint8_t count,
|
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,
|
uint8_t* driveTypeOut,
|
||||||
uint16_t* cylindersOut,
|
uint16_t* cylindersOut,
|
||||||
uint16_t* sectorsOut,
|
uint16_t* sectorsOut,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user