forked from PoliEcho-holding-org/kern
Implemented diskWrite() function!\nWe finally have disk operations!! Get ready for the filetable :)
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#define PIO_PORT 0x1f0
|
||||
#define READ_COMMAND 0x20
|
||||
#define WRITE_COMMAND 0x30
|
||||
#define CACHE_FLUSH 0xE7
|
||||
|
||||
void diskRead(uint32_t lbaAddress, uint8_t sectorCount, char* dst) {
|
||||
outb(PIO_PORT + 6, ((lbaAddress >> 24) & 0x0f) | 0xe0); // 6 - Use LBA; 4 - Drive number; 3-0 - Highest lba address nibble
|
||||
@@ -29,3 +30,29 @@ void diskRead(uint32_t lbaAddress, uint8_t sectorCount, char* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
void diskWrite(uint32_t lbaAddress, uint8_t sectorCount, char* src) {
|
||||
outb(PIO_PORT + 6, ((lbaAddress >> 24) & 0x0f) | 0xe0); // 6 - Use LBA; 4 - Drive number; 3-0 - Highest lba address nibble
|
||||
outb(PIO_PORT + 2, sectorCount); // Sector count register
|
||||
outb(PIO_PORT + 3, (uint8_t)(lbaAddress)); // Lowest lba address byte
|
||||
outb(PIO_PORT + 4, (uint8_t)(lbaAddress >> 8)); // Middle lba address byte
|
||||
outb(PIO_PORT + 5, (uint8_t)(lbaAddress >> 16)); // High lba address byte
|
||||
outb(PIO_PORT + 7, WRITE_COMMAND); // Command register
|
||||
|
||||
uint16_t* address = (uint16_t*)src;
|
||||
|
||||
for (uint8_t i = sectorCount; i > 0; i--) {
|
||||
while (inb(PIO_PORT + 7) & (1 << 7)); // Poll status register untill BSY bit is clear
|
||||
|
||||
for (size_t j = 0; j < 256; j++) {
|
||||
outw(PIO_PORT, *address++); // Write 256 words (512 Bytes = 1 Sector)
|
||||
}
|
||||
|
||||
for (uint8_t delay = 0; delay < 4; delay++) { // 400ns delay
|
||||
inb(0x3f6); // Alternate status register
|
||||
}
|
||||
}
|
||||
|
||||
outb(PIO_PORT + 7, CACHE_FLUSH); // Cache flush
|
||||
while (inb(PIO_PORT + 7) & (1 << 7)); // Poll status register untill BSY bit is clear
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
extern uint8_t driveNum;
|
||||
|
||||
void diskRead(uint32_t lbaAddress, uint8_t sectorCount, char* dst);
|
||||
// TODO: void diskWrite(uint8_t sector, uint8_t sectorCount, uint8_t drive, const char* src);
|
||||
void diskWrite(uint32_t lbaAddress, uint8_t sectorCount, char* src);
|
||||
|
||||
#endif
|
||||
|
||||
+48
-23
@@ -39,42 +39,67 @@ void main() {
|
||||
args = strchr(input, '\n');
|
||||
}
|
||||
|
||||
*args = '\0'; // Separate command from args
|
||||
args++;
|
||||
*args++ = '\0'; // Separate command from args
|
||||
|
||||
if (strcmp(input, "clear") == 0) {
|
||||
clear(0x0f);
|
||||
} else if (strcmp(input, "disk") == 0) {
|
||||
static char buf[512];
|
||||
char buf[512] = { 0 };
|
||||
|
||||
if (*args == '\0') {
|
||||
print("test: ", 0x0f);
|
||||
print("disk: ", 0x0f);
|
||||
print("No arguments given\n", 0x0c);
|
||||
print("Usage: test <sector>\n", 0x0f);
|
||||
print("Usage: disk <r/w> <sector> [data]\n", 0x0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: We only support reading right now
|
||||
//char mode = *args++;
|
||||
//if (mode != 'r' || mode != 'w') {
|
||||
// print("test: ", 0x0f);
|
||||
// print("Invalid access mode. Use r(ead) or w(rite)\n", 0x0c);
|
||||
// print("Usage: test <r/w> <sector> [data]\n", 0x0f);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
uint32_t sector = atoi(args);
|
||||
print("Reading...\n", 0x0f);
|
||||
diskRead(sector, 1, buf);
|
||||
while (isSpace(*args)) { args++; } // Skip whitespace
|
||||
char mode = *args++;
|
||||
while (isSpace(*args)) { args++; }
|
||||
|
||||
print("Contents:\n", 0x0f);
|
||||
for (size_t i = 0; i < 512; i++) {
|
||||
if (buf[i] != '\0') {
|
||||
putc(buf[i], 0x0f);
|
||||
if (mode == 'r') {
|
||||
if (*args == '\0') {
|
||||
print("disk: ", 0x0f);
|
||||
print("Sector not specified\n", 0x0c);
|
||||
print("Usage: disk <r/w> <sector> [data]\n", 0x0f);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
putc('\n', 0x0f);
|
||||
uint32_t sector = atoi(args);
|
||||
print("Reading...\n", 0x0f);
|
||||
diskRead(sector, 1, buf);
|
||||
|
||||
print("Contents:\n", 0x0f);
|
||||
for (size_t i = 0; i < 512; i++) {
|
||||
if (buf[i] != '\0') {
|
||||
putc(buf[i], 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
putc('\n', 0x0f);
|
||||
} else if (mode == 'w') {
|
||||
char* data;
|
||||
if ((data = strchr(args, ' ')) == NULL) {
|
||||
print("disk: ", 0x0f);
|
||||
print("No data given\n", 0x0c);
|
||||
print("Usage: disk <r/w> <sector> [data]\n", 0x0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
*data++ = '\0';
|
||||
uint32_t sector = atoi(args);
|
||||
|
||||
while (isSpace(*args)) { args++; } // Skip whitespace
|
||||
|
||||
strcpy(buf, data);
|
||||
print("Writing...\n", 0x0f);
|
||||
diskWrite(sector, 1, buf);
|
||||
} else {
|
||||
print("disk: ", 0x0f);
|
||||
print("Invalid access mode. Use r(ead) or w(rite)\n", 0x0c);
|
||||
print("Usage: disk <r/w> <sector> [data]\n", 0x0f);
|
||||
continue;
|
||||
}
|
||||
} else if (strcmp(input, "echo") == 0) {
|
||||
print(args, 0x0f);
|
||||
} else if (strcmp(input, "exit") == 0) {
|
||||
|
||||
@@ -30,6 +30,11 @@ uint32_t atoi(const char* str) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int isSpace(char c) {
|
||||
if (c == ' ' || c == '\t' || c == '\n') return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
// Some implementations taken from https://en.wikibooks.org/wiki/C_Programming/String_manipulation
|
||||
char* strcat(char* str1, const char* str2) {
|
||||
char* s = str1;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
char* itoa(uint32_t val, uint8_t base);
|
||||
uint32_t atoi(const char* str);
|
||||
|
||||
int isSpace(char c);
|
||||
|
||||
char* strcat(char* str1, const char* str2);
|
||||
char* strchr(const char* str, char c);
|
||||
int strcmp(const char* str1, const char* str2);
|
||||
|
||||
Reference in New Issue
Block a user