mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Moved all header files into include/ and removed their C counterparts -> code inside .h files Also added a kernel.ld linker file since we don't have many code files in src/ now, i removed src/kernel/ only real code change is that i moved memcopy() and memset() into string.h from system.h
64 lines
2.3 KiB
C
64 lines
2.3 KiB
C
#ifndef DRIVE_H
|
|
#define DRIVE_H
|
|
|
|
#include "stdint.h"
|
|
#include "system.h"
|
|
|
|
#define PIO_PORT 0x1f0
|
|
#define READ_COMMAND 0x20
|
|
#define WRITE_COMMAND 0x30
|
|
#define CACHE_FLUSH 0xE7
|
|
|
|
extern uint8_t driveNum;
|
|
|
|
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
|
|
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, READ_COMMAND); // Command register
|
|
|
|
uint16_t* address = (uint16_t*)dst;
|
|
|
|
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++) {
|
|
*address++ = inw(PIO_PORT); // Read 256 words (512 Bytes = 1 Sector)
|
|
}
|
|
|
|
for (uint8_t delay = 0; delay < 4; delay++) { // 400ns delay
|
|
inb(0x3f6); // Alternate status register
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
#endif
|